CMS 3D CMS Logo

DeepMETProducer.cc
Go to the documentation of this file.
5 
8 
11 
12 using namespace deepmet_helper;
13 
14 class DeepMETProducer : public edm::stream::EDProducer<edm::GlobalCache<tensorflow::SessionCache> > {
15 public:
17  void produce(edm::Event& event, const edm::EventSetup& setup) override;
18  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
19 
20  // static methods for handling the global cache
21  static std::unique_ptr<tensorflow::SessionCache> initializeGlobalCache(const edm::ParameterSet&);
22  static void globalEndJob(tensorflow::SessionCache*){};
23 
24 private:
26  const float norm_;
27  const bool ignore_leptons_;
28  const unsigned int max_n_pf_;
29 
30  const tensorflow::Session* session_;
31 
32  tensorflow::Tensor input_;
33  tensorflow::Tensor input_cat0_;
34  tensorflow::Tensor input_cat1_;
35  tensorflow::Tensor input_cat2_;
36 };
37 
39  : pf_token_(consumes<std::vector<pat::PackedCandidate> >(cfg.getParameter<edm::InputTag>("pf_src"))),
40  norm_(cfg.getParameter<double>("norm_factor")),
41  ignore_leptons_(cfg.getParameter<bool>("ignore_leptons")),
42  max_n_pf_(cfg.getParameter<unsigned int>("max_n_pf")),
43  session_(cache->getSession()) {
44  produces<pat::METCollection>();
45 
46  // Workaround for missing constructor TensorShape::TensorShape(absl::Slice<long>),
47  // the constructor expects Slice<int64> or initializer_list<int64> and is marked explicit
48  tensorflow::TensorShape shape;
49  shape.AddDim(1);
50  shape.AddDim(max_n_pf_);
51  shape.AddDim(8);
52 
53  tensorflow::TensorShape cat_shape;
54  cat_shape.AddDim(1);
55  cat_shape.AddDim(max_n_pf_);
56  cat_shape.AddDim(1);
57 
58  input_ = tensorflow::Tensor(tensorflow::DT_FLOAT, shape);
59  input_cat0_ = tensorflow::Tensor(tensorflow::DT_FLOAT, cat_shape);
60  input_cat1_ = tensorflow::Tensor(tensorflow::DT_FLOAT, cat_shape);
61  input_cat2_ = tensorflow::Tensor(tensorflow::DT_FLOAT, cat_shape);
62 }
63 
65  auto const& pfs = event.get(pf_token_);
66 
67  const tensorflow::NamedTensorList input_list = {
68  {"input", input_}, {"input_cat0", input_cat0_}, {"input_cat1", input_cat1_}, {"input_cat2", input_cat2_}};
69 
70  // Set all inputs to zero
71  input_.flat<float>().setZero();
72  input_cat0_.flat<float>().setZero();
73  input_cat1_.flat<float>().setZero();
74  input_cat2_.flat<float>().setZero();
75 
76  size_t i_pf = 0;
77  float px_leptons = 0.;
78  float py_leptons = 0.;
79  const float scale = 1. / norm_;
80  for (const auto& pf : pfs) {
81  if (ignore_leptons_) {
82  int pdg_id = std::abs(pf.pdgId());
83  if (pdg_id == 11 || pdg_id == 13) {
84  px_leptons += pf.px();
85  py_leptons += pf.py();
86  continue;
87  }
88  }
89 
90  // fill the tensor
91  // PF keys [b'PF_dxy', b'PF_dz', b'PF_eta', b'PF_mass', b'PF_pt', b'PF_puppiWeight', b'PF_px', b'PF_py']
92  float* ptr = &input_.tensor<float, 3>()(0, i_pf, 0);
93  *ptr = pf.dxy();
94  *(++ptr) = pf.dz();
95  *(++ptr) = pf.eta();
96  *(++ptr) = pf.mass();
97  *(++ptr) = scale_and_rm_outlier(pf.pt(), scale);
98  *(++ptr) = pf.puppiWeight();
99  *(++ptr) = scale_and_rm_outlier(pf.px(), scale);
100  *(++ptr) = scale_and_rm_outlier(pf.py(), scale);
101  input_cat0_.tensor<float, 3>()(0, i_pf, 0) = charge_embedding.at(pf.charge());
102  input_cat1_.tensor<float, 3>()(0, i_pf, 0) = pdg_id_embedding.at(pf.pdgId());
103  input_cat2_.tensor<float, 3>()(0, i_pf, 0) = pf.fromPV();
104 
105  ++i_pf;
106  if (i_pf == max_n_pf_) {
107  break; // output a warning?
108  }
109  }
110 
111  std::vector<tensorflow::Tensor> outputs;
112  const std::vector<std::string> output_names = {"output/BiasAdd"};
113 
114  // run the inference and return met
116 
117  // The DNN directly estimates the missing px and py, not the recoil
118  float px = outputs[0].tensor<float, 2>()(0, 0) * norm_;
119  float py = outputs[0].tensor<float, 2>()(0, 1) * norm_;
120 
121  px -= px_leptons;
122  py -= py_leptons;
123 
124  LogDebug("produce") << "<DeepMETProducer::produce>:" << std::endl
125  << " MET from DeepMET Producer is MET_x " << px << " and MET_y " << py << std::endl;
126 
127  auto pf_mets = std::make_unique<pat::METCollection>();
128  const reco::Candidate::LorentzVector p4(px, py, 0., std::hypot(px, py));
129  pf_mets->emplace_back(reco::MET(p4, {}));
130  event.put(std::move(pf_mets));
131 }
132 
133 std::unique_ptr<tensorflow::SessionCache> DeepMETProducer::initializeGlobalCache(const edm::ParameterSet& params) {
134  // this method is supposed to create, initialize and return a SessionCache instance
135  std::string graphPath = edm::FileInPath(params.getParameter<std::string>("graph_path")).fullPath();
136  return std::make_unique<tensorflow::SessionCache>(graphPath);
137 }
138 
141  desc.add<edm::InputTag>("pf_src", edm::InputTag("packedPFCandidates"));
142  desc.add<bool>("ignore_leptons", false);
143  desc.add<double>("norm_factor", 50.);
144  desc.add<unsigned int>("max_n_pf", 4500);
145  desc.add<std::string>("graph_path", "RecoMET/METPUSubtraction/data/models/deepmet/deepmet_v1_2018/model.graphdef");
146  descriptions.add("deepMETProducer", desc);
147 }
148 
std::vector< NamedTensor > NamedTensorList
Definition: TensorFlow.h:31
const bool ignore_leptons_
std::string fullPath() const
Definition: FileInPath.cc:161
void produce(edm::Event &event, const edm::EventSetup &setup) override
tensorflow::Tensor input_cat0_
tensorflow::Tensor input_cat1_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
tensorflow::Tensor input_
static std::unique_ptr< tensorflow::SessionCache > initializeGlobalCache(const edm::ParameterSet &)
static const std::unordered_map< int, int32_t > charge_embedding
Definition: DeepMETHelp.h:10
Definition: HeavyIon.h:7
Definition: MET.h:41
void run(Session *session, const NamedTensorList &inputs, const std::vector< std::string > &outputNames, std::vector< Tensor > *outputs, const thread::ThreadPoolOptions &threadPoolOptions)
Definition: TensorFlow.cc:259
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static const std::unordered_map< int, int32_t > pdg_id_embedding
Definition: DeepMETHelp.h:11
const tensorflow::Session * session_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
tensorflow::Tensor input_cat2_
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:36
DeepMETProducer(const edm::ParameterSet &, const tensorflow::SessionCache *)
HLT enums.
def cache(function)
Definition: utilities.py:3
float scale_and_rm_outlier(float val, float scale)
Definition: DeepMETHelper.cc:4
const unsigned int max_n_pf_
const edm::EDGetTokenT< std::vector< pat::PackedCandidate > > pf_token_
def move(src, dest)
Definition: eostools.py:511
Definition: event.py:1
const float norm_
#define LogDebug(id)