CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MLPFProducer.cc
Go to the documentation of this file.
5 
9 
10 struct MLPFCache {
11  const tensorflow::GraphDef* graph_def;
12 };
13 
14 class MLPFProducer : public edm::stream::EDProducer<edm::GlobalCache<MLPFCache> > {
15 public:
16  explicit MLPFProducer(const edm::ParameterSet&, const MLPFCache*);
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<MLPFCache> initializeGlobalCache(const edm::ParameterSet&);
22  static void globalEndJob(MLPFCache*);
23 
24 private:
28  tensorflow::Session* session_;
29 };
30 
32  : pfCandidatesPutToken_{produces<reco::PFCandidateCollection>()},
33  inputTagBlocks_(consumes<reco::PFBlockCollection>(cfg.getParameter<edm::InputTag>("src"))),
34  model_path_(cfg.getParameter<std::string>("model_path")) {
36 }
37 
39  using namespace reco::mlpf;
40 
41  const auto& blocks = event.get(inputTagBlocks_);
42  const auto& all_elements = getPFElements(blocks);
43 
44  const long long int num_elements_total = all_elements.size();
45 
46  //tensor size must be a multiple of the bin size and larger than the number of elements
47  const auto tensor_size = LSH_BIN_SIZE * (num_elements_total / LSH_BIN_SIZE + 1);
48  assert(tensor_size <= NUM_MAX_ELEMENTS_BATCH);
49 
50  //Create the input tensor
51  tensorflow::TensorShape shape({BATCH_SIZE, tensor_size, NUM_ELEMENT_FEATURES});
52  tensorflow::Tensor input(tensorflow::DT_FLOAT, shape);
53  input.flat<float>().setZero();
54 
55  //Fill the input tensor
56  unsigned int ielem = 0;
57  for (const auto* pelem : all_elements) {
58  const auto& elem = *pelem;
59 
60  //prepare the input array from the PFElement
61  const auto& props = getElementProperties(elem);
62 
63  //copy features to the input array
64  for (unsigned int iprop = 0; iprop < NUM_ELEMENT_FEATURES; iprop++) {
65  input.tensor<float, 3>()(0, ielem, iprop) = normalize(props[iprop]);
66  }
67  ielem += 1;
68  }
69 
70  //TF model input and output tensor names
71  const tensorflow::NamedTensorList input_list = {{"x:0", input}};
72  const std::vector<std::string> output_names = {"Identity:0"};
73 
74  //Prepare the output tensor
75  std::vector<tensorflow::Tensor> outputs;
76 
77  //run the GNN inference, given the inputs and the output.
78  //Note that the GNN enables information transfer between the input PFElements,
79  //such that the output ML-PFCandidates are in general combinations of the input PFElements, in the form of
80  //y_out = Adj.x_in, where x_in is input matrix (num_elem, NUM_ELEMENT_FEATURES), y_out is the output matrix (num_elem, NUM_OUTPUT_FEATURES)
81  //and Adj is an adjacency matrix between the elements that is constructed on the fly during model inference.
82  tensorflow::run(session_, input_list, output_names, &outputs);
83 
84  //process the output tensor to ML-PFCandidates.
85  //The output can contain up to num_elem particles, with predicted PDGID=0 corresponding to no particles predicted.
86  const auto out_arr = outputs[0].tensor<float, 3>();
87 
88  std::vector<reco::PFCandidate> pOutputCandidateCollection;
89  for (unsigned int ielem = 0; ielem < all_elements.size(); ielem++) {
90  //get the coefficients in the output corresponding to the class probabilities (raw logits)
91  std::vector<float> pred_id_logits;
92  for (unsigned int idx_id = 0; idx_id <= NUM_CLASS; idx_id++) {
93  pred_id_logits.push_back(out_arr(0, ielem, idx_id));
94  }
95 
96  //get the most probable class PDGID
97  int pred_pid = pdgid_encoding[argMax(pred_id_logits)];
98 
99  //get the predicted momentum components
100  float pred_eta = out_arr(0, ielem, IDX_ETA);
101  float pred_phi = out_arr(0, ielem, IDX_PHI);
102  float pred_charge = out_arr(0, ielem, IDX_CHARGE);
103  float pred_e = out_arr(0, ielem, IDX_ENERGY);
104 
105  //a particle was predicted for this PFElement, otherwise it was a spectator
106  if (pred_pid != 0) {
107  auto cand = makeCandidate(pred_pid, pred_charge, pred_e, pred_eta, pred_phi);
108  setCandidateRefs(cand, all_elements, ielem);
109  pOutputCandidateCollection.push_back(cand);
110  }
111  } //loop over PFElements
112 
113  event.emplace(pfCandidatesPutToken_, pOutputCandidateCollection);
114 }
115 
117  // this method is supposed to create, initialize and return a MLPFCache instance
118  std::unique_ptr<MLPFCache> cache = std::make_unique<MLPFCache>();
119 
120  //load the frozen TF graph of the GNN model
121  std::string path = params.getParameter<std::string>("model_path");
122  auto fullPath = edm::FileInPath(path).fullPath();
123  LogDebug("MLPFProducer") << "Initializing MLPF model from " << fullPath;
124 
125  cache->graph_def = tensorflow::loadGraphDef(fullPath);
126 
127  return cache;
128 }
129 
130 void MLPFProducer::globalEndJob(MLPFCache* cache) { delete cache->graph_def; }
131 
134  desc.add<edm::InputTag>("src", edm::InputTag("particleFlowBlock"));
135  desc.add<std::string>("model_path", "RecoParticleFlow/PFProducer/data/mlpf/mlpf_2020_11_04.pb");
136  descriptions.addWithDefaultLabel(desc);
137 }
138 
Session * createSession(SessionOptions &sessionOptions)
Definition: TensorFlow.cc:85
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
std::vector< NamedTensor > NamedTensorList
Definition: TensorFlow.h:30
static constexpr unsigned int IDX_ETA
Definition: MLPFModel.h:27
tuple cfg
Definition: looper.py:296
static constexpr unsigned int NUM_CLASS
Definition: MLPFModel.h:26
std::array< float, NUM_ELEMENT_FEATURES > getElementProperties(const reco::PFBlockElement &orig)
Definition: MLPFModel.cc:15
int argMax(std::vector< float > const &vec)
Definition: MLPFModel.cc:158
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
GraphDef * loadGraphDef(const std::string &pbFile)
Definition: TensorFlow.cc:68
static constexpr unsigned int NUM_ELEMENT_FEATURES
Definition: MLPFModel.h:10
static void globalEndJob(MLPFCache *)
tuple blocks
Definition: gather_cfg.py:90
static constexpr unsigned int IDX_ENERGY
Definition: MLPFModel.h:29
static constexpr int BATCH_SIZE
Definition: MLPFModel.h:17
assert(be >=bs)
void produce(edm::Event &event, const edm::EventSetup &setup) override
Definition: MLPFProducer.cc:38
const std::vector< const reco::PFBlockElement * > getPFElements(const reco::PFBlockCollection &blocks)
Definition: MLPFModel.cc:185
static std::string const input
Definition: EdmProvDump.cc:47
const tensorflow::GraphDef * graph_def
Definition: MLPFProducer.cc:11
static std::unique_ptr< MLPFCache > initializeGlobalCache(const edm::ParameterSet &)
const edm::EDPutTokenT< reco::PFCandidateCollection > pfCandidatesPutToken_
Definition: MLPFProducer.cc:25
void run(Session *session, const NamedTensorList &inputs, const std::vector< std::string > &outputNames, std::vector< Tensor > *outputs, const thread::ThreadPoolOptions &threadPoolOptions)
Definition: TensorFlow.cc:213
static constexpr unsigned int IDX_PHI
Definition: MLPFModel.h:28
tensorflow::Session * session_
Definition: MLPFProducer.cc:28
static constexpr unsigned int IDX_CHARGE
Definition: MLPFModel.h:30
ParameterDescriptionBase * add(U const &iLabel, T const &value)
tuple mlpf
Definition: mlpf_cff.py:4
void setCandidateRefs(reco::PFCandidate &cand, const std::vector< const reco::PFBlockElement * > elems, size_t ielem_originator)
Definition: MLPFModel.cc:204
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
float normalize(float in)
Definition: MLPFModel.cc:149
const edm::EDGetTokenT< reco::PFBlockCollection > inputTagBlocks_
Definition: MLPFProducer.cc:26
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::string fullPath() const
Definition: FileInPath.cc:161
static const std::vector< int > pdgid_encoding
Definition: MLPFModel.h:34
const std::string model_path_
Definition: MLPFProducer.cc:27
reco::PFCandidate makeCandidate(int pred_pid, int pred_charge, float pred_e, float pred_eta, float pred_phi)
Definition: MLPFModel.cc:162
static constexpr int LSH_BIN_SIZE
Definition: MLPFModel.h:14
def cache
Definition: utilities.py:3
MLPFProducer(const edm::ParameterSet &, const MLPFCache *)
Definition: MLPFProducer.cc:31
#define LogDebug(id)
static constexpr int NUM_MAX_ELEMENTS_BATCH
Definition: MLPFModel.h:13