CMS 3D CMS Logo

CaloTruthAccumulator.cc
Go to the documentation of this file.
1 #define DEBUG false
2 #if DEBUG
3 // boost optional (used by boost graph) results in some false positives with
4 // -Wmaybe-uninitialized
5 #pragma GCC diagnostic push
6 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
7 #endif
8 
9 // BOOST GRAPH LIBRARY
10 #include <boost/graph/adjacency_list.hpp>
11 #include <boost/graph/breadth_first_search.hpp>
12 #include <boost/graph/depth_first_search.hpp>
13 #include <boost/graph/graphviz.hpp>
14 
15 #if DEBUG
16 #pragma GCC diagnostic pop
17 #endif
18 
19 #include <iterator>
20 #include <memory>
21 
22 #include <numeric> // for std::accumulate
23 #include <unordered_map>
24 
33 
40 
49 
54 
60 
61 namespace {
62  using Index_t = unsigned;
63  using Barcode_t = int;
64  const std::string messageCategoryGraph_("CaloTruthAccumulatorGraphProducer");
65 } // namespace
66 
67 using boost::add_edge;
68 using boost::adjacency_list;
69 using boost::directedS;
70 using boost::edge;
71 using boost::edge_weight;
72 using boost::edge_weight_t;
73 using boost::listS;
74 using boost::property;
75 using boost::vecS;
76 using boost::vertex;
77 using boost::vertex_name;
78 using boost::vertex_name_t;
79 
80 /* GRAPH DEFINITIONS
81 
82  The graphs represent the full decay chain.
83 
84  The parent-child relationship is the natural one, following "time".
85 
86  Each edge has a property (edge_weight_t) that holds a const pointer to the
87  SimTrack that connects the 2 vertices of the edge, the number of simHits
88  associated to that simTrack and the cumulative number of simHits of itself
89  and of all its children. Only simHits within the selected detectors are
90  taken into account. The cumulative property is filled during the dfs
91  exploration of the graph: if not explored the number is 0.
92 
93  Each vertex has a property (vertex_name_t) that holds a const pointer to the
94  SimTrack that originated that vertex and the cumulative number of simHits of
95  all its outgoing edges. The cumulative property is filled during the dfs
96  exploration of the graph: if not explored the number is 0.
97 
98  Stable particles are recovered/added in a second iterations and are linked
99  to ghost vertices with an offset starting from the highest generated vertex.
100 
101  Multiple decays of a single particle that retains its original trackId are
102  merged into one unique vertex (the first encountered) in order to avoid
103  multiple counting of its associated simHits (if any).
104 
105 */
106 struct EdgeProperty {
109  int simHits;
111 };
112 
120 };
121 
122 using EdgeParticleClustersProperty = property<edge_weight_t, EdgeProperty>;
123 using VertexMotherParticleProperty = property<vertex_name_t, VertexProperty>;
124 using DecayChain = adjacency_list<listS, vecS, directedS, VertexMotherParticleProperty, EdgeParticleClustersProperty>;
125 
127 public:
129 
130 private:
131  void initializeEvent(const edm::Event &event, const edm::EventSetup &setup) override;
132  void accumulate(const edm::Event &event, const edm::EventSetup &setup) override;
133  void accumulate(const PileUpEventPrincipal &event, const edm::EventSetup &setup, edm::StreamID const &) override;
134  void finalizeEvent(edm::Event &event, const edm::EventSetup &setup) override;
136 
138  template <class T>
139  void accumulateEvent(const T &event,
140  const edm::EventSetup &setup,
141  const edm::Handle<edm::HepMCProduct> &hepMCproduct);
142 
145  template <class T>
146  void fillSimHits(std::vector<std::pair<DetId, const PCaloHit *>> &returnValue,
147  std::unordered_map<int, std::map<int, float>> &simTrackDetIdEnergyMap,
148  const T &event,
149  const edm::EventSetup &setup);
150 
152 
153  std::unordered_map<Index_t, float> m_detIdToTotalSimEnergy; // keep track of cell normalizations
154  std::unordered_multimap<Barcode_t, Index_t> m_simHitBarcodeToIndex;
155 
161  const unsigned int maximumPreviousBunchCrossing_;
168 
173 
174  std::vector<edm::InputTag> collectionTags_;
178 
180  const bool premixStage1_;
181 
182 public:
184  std::unique_ptr<SimClusterCollection> pSimClusters;
185  std::unique_ptr<CaloParticleCollection> pCaloParticles;
186  };
187 
188  struct calo_particles {
189  std::vector<uint32_t> sc_start_;
190  std::vector<uint32_t> sc_stop_;
191 
192  void swap(calo_particles &oth) {
193  sc_start_.swap(oth.sc_start_);
194  sc_stop_.swap(oth.sc_stop_);
195  }
196 
197  void clear() {
198  sc_start_.clear();
199  sc_stop_.clear();
200  }
201  };
202 
203 private:
204  const HGCalTopology *hgtopo_[3] = {nullptr, nullptr, nullptr};
205  const HGCalDDDConstants *hgddd_[3] = {nullptr, nullptr, nullptr};
206  const HcalDDDRecConstants *hcddd_ = nullptr;
209  // geometry type (0 pre-TDR; 1 TDR)
211  bool doHGCAL;
212 };
213 
214 /* Graph utility functions */
215 
216 namespace {
217  template <typename Edge, typename Graph, typename Visitor>
218  void accumulateSimHits_edge(Edge &e, const Graph &g, Visitor *v) {
219  auto const edge_property = get(edge_weight, g, e);
220  v->total_simHits += edge_property.simHits;
221  IfLogDebug(DEBUG, messageCategoryGraph_)
222  << " Examining edges " << e << " --> particle " << edge_property.simTrack->type() << "("
223  << edge_property.simTrack->trackId() << ")"
224  << " with SimClusters: " << edge_property.simHits << " Accumulated SimClusters: " << v->total_simHits
225  << std::endl;
226  }
227  template <typename Vertex, typename Graph>
228  void print_vertex(Vertex &u, const Graph &g) {
229  auto const vertex_property = get(vertex_name, g, u);
230  IfLogDebug(DEBUG, messageCategoryGraph_) << " At " << u;
231  // The Mother of all vertices has **no** SimTrack associated.
232  if (vertex_property.simTrack)
233  IfLogDebug(DEBUG, messageCategoryGraph_) << " [" << vertex_property.simTrack->type() << "]"
234  << "(" << vertex_property.simTrack->trackId() << ")";
235  IfLogDebug(DEBUG, messageCategoryGraph_) << std::endl;
236  }
237 
238 // Graphviz output functions will only be generated in DEBUG mode
239 #if DEBUG
240  std::string graphviz_vertex(const VertexProperty &v) {
241  std::ostringstream oss;
242  oss << "{id: " << (v.simTrack ? v.simTrack->trackId() : 0) << ",\\ntype: " << (v.simTrack ? v.simTrack->type() : 0)
243  << ",\\nchits: " << v.cumulative_simHits << "}";
244  return oss.str();
245  }
246 
247  std::string graphviz_edge(const EdgeProperty &e) {
248  std::ostringstream oss;
249  oss << "[" << (e.simTrack ? e.simTrack->trackId() : 0) << "," << (e.simTrack ? e.simTrack->type() : 0) << ","
250  << e.simHits << "," << e.cumulative_simHits << "]";
251  return oss.str();
252  }
253 #endif
254 
255  class SimHitsAccumulator_dfs_visitor : public boost::default_dfs_visitor {
256  public:
257  int total_simHits = 0;
258  template <typename Edge, typename Graph>
259  void examine_edge(Edge e, const Graph &g) {
260  accumulateSimHits_edge(e, g, this);
261  }
262  template <typename Edge, typename Graph>
263  void finish_edge(Edge e, const Graph &g) {
264  auto const edge_property = get(edge_weight, g, e);
265  auto src = source(e, g);
266  auto trg = target(e, g);
267  auto cumulative = edge_property.simHits + get(vertex_name, g, trg).cumulative_simHits +
268  (get(vertex_name, g, src).simTrack ? get(vertex_name, g, src).cumulative_simHits
269  : 0); // when we hit the root vertex we have to stop
270  // adding back its contribution.
271  auto const src_vertex_property = get(vertex_name, g, src);
272  put(get(vertex_name, const_cast<Graph &>(g)), src, VertexProperty(src_vertex_property.simTrack, cumulative));
273  put(get(edge_weight, const_cast<Graph &>(g)),
274  e,
275  EdgeProperty(edge_property.simTrack, edge_property.simHits, cumulative));
276  IfLogDebug(DEBUG, messageCategoryGraph_)
277  << " Finished edge: " << e << " Track id: " << get(edge_weight, g, e).simTrack->trackId()
278  << " has accumulated " << cumulative << " hits" << std::endl;
279  IfLogDebug(DEBUG, messageCategoryGraph_) << " SrcVtx: " << src << "\t" << get(vertex_name, g, src).simTrack
280  << "\t" << get(vertex_name, g, src).cumulative_simHits << std::endl;
281  IfLogDebug(DEBUG, messageCategoryGraph_) << " TrgVtx: " << trg << "\t" << get(vertex_name, g, trg).simTrack
282  << "\t" << get(vertex_name, g, trg).cumulative_simHits << std::endl;
283  }
284  };
285 
287 
288  class CaloParticle_dfs_visitor : public boost::default_dfs_visitor {
289  public:
290  CaloParticle_dfs_visitor(CaloTruthAccumulator::OutputCollections &output,
292  std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex,
293  std::unordered_map<int, std::map<int, float>> &simTrackDetIdEnergyMap,
294  Selector selector)
295  : output_(output),
296  caloParticles_(caloParticles),
297  simHitBarcodeToIndex_(simHitBarcodeToIndex),
298  simTrackDetIdEnergyMap_(simTrackDetIdEnergyMap),
299  selector_(selector) {}
300  template <typename Vertex, typename Graph>
301  void discover_vertex(Vertex u, const Graph &g) {
302  // If we reach the vertex 0, it means that we are backtracking with respect
303  // to the first generation of stable particles: simply return;
304  // if (u == 0) return;
305  print_vertex(u, g);
306  auto const vertex_property = get(vertex_name, g, u);
307  if (!vertex_property.simTrack)
308  return;
309  auto trackIdx = vertex_property.simTrack->trackId();
310  IfLogDebug(DEBUG, messageCategoryGraph_)
311  << " Found " << simHitBarcodeToIndex_.count(trackIdx) << " associated simHits" << std::endl;
312  if (simHitBarcodeToIndex_.count(trackIdx)) {
313  output_.pSimClusters->emplace_back(*vertex_property.simTrack);
314  auto &simcluster = output_.pSimClusters->back();
315  std::unordered_map<uint32_t, float> acc_energy;
316  for (auto const &hit_and_energy : simTrackDetIdEnergyMap_[trackIdx]) {
317  acc_energy[hit_and_energy.first] += hit_and_energy.second;
318  }
319  for (auto const &hit_and_energy : acc_energy) {
320  simcluster.addRecHitAndFraction(hit_and_energy.first, hit_and_energy.second);
321  }
322  }
323  }
324  template <typename Edge, typename Graph>
325  void examine_edge(Edge e, const Graph &g) {
326  auto src = source(e, g);
327  auto vertex_property = get(vertex_name, g, src);
328  if (src == 0 or (vertex_property.simTrack == nullptr)) {
329  auto edge_property = get(edge_weight, g, e);
330  IfLogDebug(DEBUG, messageCategoryGraph_) << "Considering CaloParticle: " << edge_property.simTrack->trackId();
331  if (selector_(edge_property)) {
332  IfLogDebug(DEBUG, messageCategoryGraph_) << "Adding CaloParticle: " << edge_property.simTrack->trackId();
333  output_.pCaloParticles->emplace_back(*(edge_property.simTrack));
334  caloParticles_.sc_start_.push_back(output_.pSimClusters->size());
335  }
336  }
337  }
338 
339  template <typename Edge, typename Graph>
340  void finish_edge(Edge e, const Graph &g) {
341  auto src = source(e, g);
342  auto vertex_property = get(vertex_name, g, src);
343  if (src == 0 or (vertex_property.simTrack == nullptr)) {
344  auto edge_property = get(edge_weight, g, e);
345  if (selector_(edge_property)) {
346  caloParticles_.sc_stop_.push_back(output_.pSimClusters->size());
347  }
348  }
349  }
350 
351  private:
353  CaloTruthAccumulator::calo_particles &caloParticles_;
354  std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex_;
355  std::unordered_map<int, std::map<int, float>> &simTrackDetIdEnergyMap_;
356  Selector selector_;
357  };
358 } // namespace
359 
361  edm::ProducesCollector producesCollector,
363  : messageCategory_("CaloTruthAccumulator"),
364  maximumPreviousBunchCrossing_(config.getParameter<unsigned int>("maximumPreviousBunchCrossing")),
365  maximumSubsequentBunchCrossing_(config.getParameter<unsigned int>("maximumSubsequentBunchCrossing")),
366  simTrackLabel_(config.getParameter<edm::InputTag>("simTrackCollection")),
367  simVertexLabel_(config.getParameter<edm::InputTag>("simVertexCollection")),
368  collectionTags_(),
369  genParticleLabel_(config.getParameter<edm::InputTag>("genParticleCollection")),
370  hepMCproductLabel_(config.getParameter<edm::InputTag>("HepMCProductLabel")),
371  minEnergy_(config.getParameter<double>("MinEnergy")),
372  maxPseudoRapidity_(config.getParameter<double>("MaxPseudoRapidity")),
373  premixStage1_(config.getParameter<bool>("premixStage1")),
374  geometryType_(-1),
375  doHGCAL(config.getParameter<bool>("doHGCAL")) {
376  producesCollector.produces<SimClusterCollection>("MergedCaloTruth");
377  producesCollector.produces<CaloParticleCollection>("MergedCaloTruth");
378  if (premixStage1_) {
379  producesCollector.produces<std::vector<std::pair<unsigned int, float>>>("MergedCaloTruth");
380  }
381 
382  iC.consumes<std::vector<SimTrack>>(simTrackLabel_);
383  iC.consumes<std::vector<SimVertex>>(simVertexLabel_);
384  iC.consumes<std::vector<reco::GenParticle>>(genParticleLabel_);
385  iC.consumes<std::vector<int>>(genParticleLabel_);
386  iC.consumes<std::vector<int>>(hepMCproductLabel_);
387 
388  // Fill the collection tags
389  const edm::ParameterSet &simHitCollectionConfig = config.getParameterSet("simHitCollections");
390  std::vector<std::string> parameterNames = simHitCollectionConfig.getParameterNames();
391 
392  for (auto const &parameterName : parameterNames) {
393  std::vector<edm::InputTag> tags = simHitCollectionConfig.getParameter<std::vector<edm::InputTag>>(parameterName);
394  collectionTags_.insert(collectionTags_.end(), tags.begin(), tags.end());
395  }
396 
397  for (auto const &collectionTag : collectionTags_) {
398  iC.consumes<std::vector<PCaloHit>>(collectionTag);
399  }
400 }
401 
404  iSetup.get<CaloGeometryRecord>().get(geom);
405  const HGCalGeometry *eegeom = nullptr, *fhgeom = nullptr, *bhgeomnew = nullptr;
406  const HcalGeometry *bhgeom = nullptr;
407  bhgeom = static_cast<const HcalGeometry *>(geom->getSubdetectorGeometry(DetId::Hcal, HcalEndcap));
408 
409  if (doHGCAL) {
410  eegeom = static_cast<const HGCalGeometry *>(
411  geom->getSubdetectorGeometry(DetId::HGCalEE, ForwardSubdetector::ForwardEmpty));
412  // check if it's the new geometry
413  if (eegeom) {
414  geometryType_ = 1;
415  fhgeom = static_cast<const HGCalGeometry *>(
416  geom->getSubdetectorGeometry(DetId::HGCalHSi, ForwardSubdetector::ForwardEmpty));
417  bhgeomnew = static_cast<const HGCalGeometry *>(
418  geom->getSubdetectorGeometry(DetId::HGCalHSc, ForwardSubdetector::ForwardEmpty));
419  } else {
420  geometryType_ = 0;
421  eegeom = static_cast<const HGCalGeometry *>(geom->getSubdetectorGeometry(DetId::Forward, HGCEE));
422  fhgeom = static_cast<const HGCalGeometry *>(geom->getSubdetectorGeometry(DetId::Forward, HGCHEF));
423  bhgeom = static_cast<const HcalGeometry *>(geom->getSubdetectorGeometry(DetId::Hcal, HcalEndcap));
424  }
425  hgtopo_[0] = &(eegeom->topology());
426  hgtopo_[1] = &(fhgeom->topology());
427  if (bhgeomnew)
428  hgtopo_[2] = &(bhgeomnew->topology());
429 
430  for (unsigned i = 0; i < 3; ++i) {
431  if (hgtopo_[i])
432  hgddd_[i] = &(hgtopo_[i]->dddConstants());
433  }
434  }
435 
436  if (bhgeom) {
437  hcddd_ = bhgeom->topology().dddConstants();
438  }
439 }
440 
442  output_.pSimClusters = std::make_unique<SimClusterCollection>();
443  output_.pCaloParticles = std::make_unique<CaloParticleCollection>();
444 
445  m_detIdToTotalSimEnergy.clear();
446 }
447 
457  event.getByLabel(hepMCproductLabel_, hepmc);
458 
459  edm::LogInfo(messageCategory_) << " CaloTruthAccumulator::accumulate (signal)";
460  accumulateEvent(event, setup, hepmc);
461 }
462 
464  edm::EventSetup const &setup,
465  edm::StreamID const &) {
466  if (event.bunchCrossing() >= -static_cast<int>(maximumPreviousBunchCrossing_) &&
467  event.bunchCrossing() <= static_cast<int>(maximumSubsequentBunchCrossing_)) {
468  // simply create empty handle as we do not have a HepMCProduct in PU anyway
470  edm::LogInfo(messageCategory_) << " CaloTruthAccumulator::accumulate (pileup) bunchCrossing="
471  << event.bunchCrossing();
472  accumulateEvent(event, setup, hepmc);
473  } else {
474  edm::LogInfo(messageCategory_) << "Skipping pileup event for bunch crossing " << event.bunchCrossing();
475  }
476 }
477 
479  edm::LogInfo(messageCategory_) << "Adding " << output_.pSimClusters->size() << " SimParticles and "
480  << output_.pCaloParticles->size() << " CaloParticles to the event.";
481 
482  // We need to normalize the hits and energies into hits and fractions (since
483  // we have looped over all pileup events)
484  // For premixing stage1 we keep the energies, they will be normalized to
485  // fractions in stage2
486 
487  if (premixStage1_) {
488  auto totalEnergies = std::make_unique<std::vector<std::pair<unsigned int, float>>>();
489  totalEnergies->reserve(m_detIdToTotalSimEnergy.size());
490  std::copy(m_detIdToTotalSimEnergy.begin(), m_detIdToTotalSimEnergy.end(), std::back_inserter(*totalEnergies));
491  std::sort(totalEnergies->begin(), totalEnergies->end());
492  event.put(std::move(totalEnergies), "MergedCaloTruth");
493  } else {
494  for (auto &sc : *(output_.pSimClusters)) {
495  auto hitsAndEnergies = sc.hits_and_fractions();
496  sc.clearHitsAndFractions();
497  sc.clearHitsEnergy();
498  for (auto &hAndE : hitsAndEnergies) {
499  const float totalenergy = m_detIdToTotalSimEnergy[hAndE.first];
500  float fraction = 0.;
501  if (totalenergy > 0)
502  fraction = hAndE.second / totalenergy;
503  else
505  << "TotalSimEnergy for hit " << hAndE.first << " is 0! The fraction for this hit cannot be computed.";
506  sc.addRecHitAndFraction(hAndE.first, fraction);
507  sc.addHitEnergy(hAndE.second);
508  }
509  }
510  }
511 
512  // save the SimCluster orphan handle so we can fill the calo particles
513  auto scHandle = event.put(std::move(output_.pSimClusters), "MergedCaloTruth");
514 
515  // now fill the calo particles
516  for (unsigned i = 0; i < output_.pCaloParticles->size(); ++i) {
517  auto &cp = (*output_.pCaloParticles)[i];
518  for (unsigned j = m_caloParticles.sc_start_[i]; j < m_caloParticles.sc_stop_[i]; ++j) {
519  edm::Ref<SimClusterCollection> ref(scHandle, j);
520  cp.addSimCluster(ref);
521  }
522  }
523 
524  event.put(std::move(output_.pCaloParticles), "MergedCaloTruth");
525 
527 
528  std::unordered_map<Index_t, float>().swap(m_detIdToTotalSimEnergy);
529  std::unordered_multimap<Barcode_t, Index_t>().swap(m_simHitBarcodeToIndex);
530 }
531 
532 template <class T>
534  const edm::EventSetup &setup,
535  const edm::Handle<edm::HepMCProduct> &hepMCproduct) {
537  edm::Handle<std::vector<int>> hGenParticleIndices;
538 
539  event.getByLabel(simTrackLabel_, hSimTracks);
540  event.getByLabel(simVertexLabel_, hSimVertices);
541 
542  event.getByLabel(genParticleLabel_, hGenParticles);
543  event.getByLabel(genParticleLabel_, hGenParticleIndices);
544 
545  std::vector<std::pair<DetId, const PCaloHit *>> simHitPointers;
546  std::unordered_map<int, std::map<int, float>> simTrackDetIdEnergyMap;
547  fillSimHits(simHitPointers, simTrackDetIdEnergyMap, event, setup);
548 
549  // Clear maps from previous event fill them for this one
550  m_simHitBarcodeToIndex.clear();
551  for (unsigned int i = 0; i < simHitPointers.size(); ++i) {
552  m_simHitBarcodeToIndex.emplace(simHitPointers[i].second->geantTrackId(), i);
553  }
554 
555  auto const &tracks = *hSimTracks;
556  auto const &vertices = *hSimVertices;
557  std::unordered_map<int, int> trackid_to_track_index;
559  int idx = 0;
560 
561  IfLogDebug(DEBUG, messageCategory_) << " TRACKS" << std::endl;
562  for (auto const &t : tracks) {
563  IfLogDebug(DEBUG, messageCategory_) << " " << idx << "\t" << t.trackId() << "\t" << t << std::endl;
564  trackid_to_track_index[t.trackId()] = idx;
565  idx++;
566  }
567 
594  idx = 0;
595  std::vector<int> used_sim_tracks(tracks.size(), 0);
596  std::vector<int> collapsed_vertices(vertices.size(), 0);
597  IfLogDebug(DEBUG, messageCategory_) << " VERTICES" << std::endl;
598  for (auto const &v : vertices) {
599  IfLogDebug(DEBUG, messageCategory_) << " " << idx++ << "\t" << v << std::endl;
600  if (v.parentIndex() != -1) {
601  auto trk_idx = trackid_to_track_index[v.parentIndex()];
602  auto origin_vtx = tracks[trk_idx].vertIndex();
603  if (used_sim_tracks[trk_idx]) {
604  // collapse the vertex into the original first vertex we saw associated
605  // to this track. Omit adding the edge in order to avoid double
606  // counting of the very same particles and its associated hits.
607  collapsed_vertices[v.vertexId()] = used_sim_tracks[trk_idx];
608  continue;
609  }
610  // Perform the actual vertex collapsing, if needed.
611  if (collapsed_vertices[origin_vtx])
612  origin_vtx = collapsed_vertices[origin_vtx];
613  add_edge(origin_vtx,
614  v.vertexId(),
615  EdgeProperty(&tracks[trk_idx], simTrackDetIdEnergyMap[v.parentIndex()].size(), 0),
616  decay);
617  used_sim_tracks[trk_idx] = v.vertexId();
618  }
619  }
620  // Build the motherParticle property to each vertex
621  auto const &vertexMothersProp = get(vertex_name, decay);
622  // Now recover the particles that did not decay. Append them with an index
623  // bigger than the size of the generated vertices.
624  int offset = vertices.size();
625  for (size_t i = 0; i < tracks.size(); ++i) {
626  if (!used_sim_tracks[i]) {
627  auto origin_vtx = tracks[i].vertIndex();
628  // Perform the actual vertex collapsing, if needed.
629  if (collapsed_vertices[origin_vtx])
630  origin_vtx = collapsed_vertices[origin_vtx];
631  add_edge(
632  origin_vtx, offset, EdgeProperty(&tracks[i], simTrackDetIdEnergyMap[tracks[i].trackId()].size(), 0), decay);
633  // The properties for "fake" vertices associated to stable particles have
634  // to be set inside this loop, since they do not belong to the vertices
635  // collection and would be skipped by that loop (coming next)
636  put(vertexMothersProp, offset, VertexProperty(&tracks[i], 0));
637  offset++;
638  }
639  }
640  for (auto const &v : vertices) {
641  if (v.parentIndex() != -1) {
642  // Skip collapsed_vertices
643  if (collapsed_vertices[v.vertexId()])
644  continue;
645  put(vertexMothersProp, v.vertexId(), VertexProperty(&tracks[trackid_to_track_index[v.parentIndex()]], 0));
646  }
647  }
648  SimHitsAccumulator_dfs_visitor vis;
649  depth_first_search(decay, visitor(vis));
650  CaloParticle_dfs_visitor caloParticleCreator(
651  output_,
654  simTrackDetIdEnergyMap,
655  [&](EdgeProperty &edge_property) -> bool {
656  // Apply selection on SimTracks in order to promote them to be
657  // CaloParticles. The function returns TRUE if the particle satisfies
658  // the selection, FALSE otherwise. Therefore the correct logic to select
659  // the particle is to ask for TRUE as return value.
660  return (edge_property.cumulative_simHits != 0 and !edge_property.simTrack->noGenpart() and
661  edge_property.simTrack->momentum().E() > minEnergy_ and
662  std::abs(edge_property.simTrack->momentum().Eta()) < maxPseudoRapidity_);
663  });
664  depth_first_search(decay, visitor(caloParticleCreator));
665 
666 #if DEBUG
667  boost::write_graphviz(std::cout,
668  decay,
669  make_label_writer(make_transform_value_property_map(&graphviz_vertex, get(vertex_name, decay))),
670  make_label_writer(make_transform_value_property_map(&graphviz_edge, get(edge_weight, decay))));
671 #endif
672 }
673 
674 template <class T>
675 void CaloTruthAccumulator::fillSimHits(std::vector<std::pair<DetId, const PCaloHit *>> &returnValue,
676  std::unordered_map<int, std::map<int, float>> &simTrackDetIdEnergyMap,
677  const T &event,
678  const edm::EventSetup &setup) {
679  for (auto const &collectionTag : collectionTags_) {
681  const bool isHcal = (collectionTag.instance().find("HcalHits") != std::string::npos);
682  event.getByLabel(collectionTag, hSimHits);
683 
684  for (auto const &simHit : *hSimHits) {
685  DetId id(0);
686 
687  //Relabel as necessary for HGCAL
688  if (doHGCAL) {
689  const uint32_t simId = simHit.id();
690  if (geometryType_ == 1) {
691  // no test numbering in new geometry
692  id = simId;
693  } else if (isHcal) {
695  if (hid.subdet() == HcalEndcap)
696  id = hid;
697  } else {
698  int subdet, layer, cell, sec, subsec, zp;
699  HGCalTestNumbering::unpackHexagonIndex(simId, subdet, zp, layer, sec, subsec, cell);
700  const HGCalDDDConstants *ddd = hgddd_[subdet - 3];
701  std::pair<int, int> recoLayerCell = ddd->simToReco(cell, layer, sec, hgtopo_[subdet - 3]->detectorType());
702  cell = recoLayerCell.first;
703  layer = recoLayerCell.second;
704  // skip simhits with bad barcodes or non-existant layers
705  if (layer == -1 || simHit.geantTrackId() == 0)
706  continue;
707  id = HGCalDetId((ForwardSubdetector)subdet, zp, layer, subsec, sec, cell);
708  }
709  } else {
710  id = simHit.id();
711  //Relabel all HCAL hits
712  if (isHcal) {
714  id = hid;
715  }
716  }
717 
718  if (id == DetId(0)) {
719  continue;
720  }
721  if (simHit.geantTrackId() == 0) {
722  continue;
723  }
724 
725  returnValue.emplace_back(id, &simHit);
726  simTrackDetIdEnergyMap[simHit.geantTrackId()][id.rawId()] += simHit.energy();
727  m_detIdToTotalSimEnergy[id.rawId()] += simHit.energy();
728  }
729  } // end of loop over InputTags
730 }
731 
732 // Register with the framework
edm::StreamID
Definition: StreamID.h:30
CaloTruthAccumulator::m_simHitBarcodeToIndex
std::unordered_multimap< Barcode_t, Index_t > m_simHitBarcodeToIndex
Definition: CaloTruthAccumulator.cc:154
CaloTruthAccumulator::hSimVertices
edm::Handle< std::vector< SimVertex > > hSimVertices
Definition: CaloTruthAccumulator.cc:172
CaloTruthAccumulator::fillSimHits
void fillSimHits(std::vector< std::pair< DetId, const PCaloHit * >> &returnValue, std::unordered_map< int, std::map< int, float >> &simTrackDetIdEnergyMap, const T &event, const edm::EventSetup &setup)
Fills the supplied vector with pointers to the SimHits, checking for bad modules if required.
Definition: CaloTruthAccumulator.cc:675
CoreSimTrack::momentum
const math::XYZTLorentzVectorD & momentum() const
Definition: CoreSimTrack.h:19
put
void put(edm::Event &evt, double value, const char *instanceName)
Definition: EventShapeVarsProducer.cc:27
Selector
Functor that operates on <T>
Definition: Selector.h:22
SimClusterCollection
std::vector< SimCluster > SimClusterCollection
Definition: SimClusterFwd.h:8
electrons_cff.bool
bool
Definition: electrons_cff.py:366
mps_fire.i
i
Definition: mps_fire.py:428
PixelSubdetector.h
HGCalTopology::dddConstants
const HGCalDDDConstants & dddConstants() const
Definition: HGCalTopology.h:98
MessageLogger.h
CaloTruthAccumulator::initializeEvent
void initializeEvent(const edm::Event &event, const edm::EventSetup &setup) override
Definition: CaloTruthAccumulator.cc:441
ForwardEmpty
Definition: ForwardSubdetector.h:5
filterCSVwithJSON.copy
copy
Definition: filterCSVwithJSON.py:36
ESHandle.h
CaloTruthAccumulator::calo_particles::clear
void clear()
Definition: CaloTruthAccumulator.cc:197
edm::LuminosityBlock
Definition: LuminosityBlock.h:50
convertSQLitetoXML_cfg.output
output
Definition: convertSQLitetoXML_cfg.py:72
ForwardSubdetector
ForwardSubdetector
Definition: ForwardSubdetector.h:4
CaloGeometryRecord
Definition: CaloGeometryRecord.h:30
edm
HLT enums.
Definition: AlignableModifier.h:19
RawDataTask_cfi.cumulative
cumulative
Definition: RawDataTask_cfi.py:196
CaloTruthAccumulator::OutputCollections::pSimClusters
std::unique_ptr< SimClusterCollection > pSimClusters
Definition: CaloTruthAccumulator.cc:184
CaloTruthAccumulator::OutputCollections
Definition: CaloTruthAccumulator.cc:183
CaloTruthAccumulator::calo_particles::sc_stop_
std::vector< uint32_t > sc_stop_
Definition: CaloTruthAccumulator.cc:190
gather_cfg.cout
cout
Definition: gather_cfg.py:144
HGCalTestNumbering::unpackHexagonIndex
static void unpackHexagonIndex(const uint32_t &idx, int &subdet, int &z, int &lay, int &wafer, int &celltyp, int &cell)
Definition: HGCalTestNumbering.cc:46
CaloTruthAccumulator::hgtopo_
const HGCalTopology * hgtopo_[3]
Definition: CaloTruthAccumulator.cc:204
DetId::Hcal
Definition: DetId.h:28
CaloParticleFwd.h
HLT_FULL_cff.InputTag
InputTag
Definition: HLT_FULL_cff.py:89285
edm::second
U second(std::pair< T, U > const &p)
Definition: ParameterSet.cc:222
PileUpEventPrincipal
Definition: PileUpEventPrincipal.h:19
CaloTruthAccumulator::maximumPreviousBunchCrossing_
const unsigned int maximumPreviousBunchCrossing_
Definition: CaloTruthAccumulator.cc:161
CaloTruthAccumulator::beginLuminosityBlock
void beginLuminosityBlock(edm::LuminosityBlock const &lumi, edm::EventSetup const &setup) override
Definition: CaloTruthAccumulator.cc:402
hgcal_conditions::parameters
Definition: HGCConditions.h:86
HcalTestNumbering.h
edm::LogInfo
Log< level::Info, false > LogInfo
Definition: MessageLogger.h:125
findQualityFiles.v
v
Definition: findQualityFiles.py:179
EcalMappingRecord_cfi.eegeom
eegeom
Definition: EcalMappingRecord_cfi.py:3
edm::Handle< edm::HepMCProduct >
edm::LogWarning
Log< level::Warning, false > LogWarning
Definition: MessageLogger.h:122
DEBUG
#define DEBUG
Definition: CaloTruthAccumulator.cc:1
singleTopDQM_cfi.setup
setup
Definition: singleTopDQM_cfi.py:37
CaloTruthAccumulator::minEnergy_
const double minEnergy_
Definition: CaloTruthAccumulator.cc:179
CaloTruthAccumulator::accumulate
void accumulate(const edm::Event &event, const edm::EventSetup &setup) override
Definition: CaloTruthAccumulator.cc:455
HcalGeometry.h
CaloTruthAccumulator::simVertexLabel_
const edm::InputTag simVertexLabel_
Definition: CaloTruthAccumulator.cc:170
CaloTruthAccumulator::maxPseudoRapidity_
const double maxPseudoRapidity_
Definition: CaloTruthAccumulator.cc:179
ProducesCollector.h
edm::Ref
Definition: AssociativeIterator.h:58
HGCalDDDConstants
Definition: HGCalDDDConstants.h:27
CaloTruthAccumulator::maximumSubsequentBunchCrossing_
const unsigned int maximumSubsequentBunchCrossing_
Definition: CaloTruthAccumulator.cc:167
heavyIonCSV_trainingSettings.idx
idx
Definition: heavyIonCSV_trainingSettings.py:5
SimTrack::noGenpart
bool noGenpart() const
Definition: SimTrack.h:38
VertexMotherParticleProperty
property< vertex_name_t, VertexProperty > VertexMotherParticleProperty
Definition: CaloTruthAccumulator.cc:123
GenParticle.h
config
Definition: config.py:1
DetId
Definition: DetId.h:17
VertexProperty::cumulative_simHits
int cumulative_simHits
Definition: CaloTruthAccumulator.cc:119
DetId::HGCalHSi
Definition: DetId.h:33
DetId::HGCalEE
Definition: DetId.h:32
SimCluster.h
HGCalDDDConstants::simToReco
std::pair< int, int > simToReco(int cell, int layer, int mod, bool half) const
Definition: HGCalDDDConstants.cc:1018
CaloTruthAccumulator::calo_particles::sc_start_
std::vector< uint32_t > sc_start_
Definition: CaloTruthAccumulator.cc:189
edm::EventSetup::get
T get() const
Definition: EventSetup.h:87
CaloTruthAccumulator::CaloTruthAccumulator
CaloTruthAccumulator(const edm::ParameterSet &config, edm::ProducesCollector, edm::ConsumesCollector &iC)
Definition: CaloTruthAccumulator.cc:360
HLT_FULL_cff.fraction
fraction
Definition: HLT_FULL_cff.py:52806
CaloTruthAccumulator::m_detIdToTotalSimEnergy
std::unordered_map< Index_t, float > m_detIdToTotalSimEnergy
Definition: CaloTruthAccumulator.cc:153
DigiAccumulatorMixMod.h
rpcPointValidation_cfi.simHit
simHit
Definition: rpcPointValidation_cfi.py:24
EdgeParticleClustersProperty
property< edge_weight_t, EdgeProperty > EdgeParticleClustersProperty
Definition: CaloTruthAccumulator.cc:122
caloTruthCellsProducer_cfi.caloParticles
caloParticles
Definition: caloTruthCellsProducer_cfi.py:6
SimVertex.h
runTauDisplay.vis
vis
Definition: runTauDisplay.py:328
CaloTruthAccumulator::OutputCollections::pCaloParticles
std::unique_ptr< CaloParticleCollection > pCaloParticles
Definition: CaloTruthAccumulator.cc:185
source
static const std::string source
Definition: EdmProvDump.cc:47
edm::ESHandle< CaloGeometry >
CaloTruthAccumulator::output_
OutputCollections output_
Definition: CaloTruthAccumulator.cc:207
PileUpEventPrincipal.h
relativeConstraints.geom
geom
Definition: relativeConstraints.py:72
edm::ConsumesCollector::consumes
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
Definition: ConsumesCollector.h:55
trackingPlots.other
other
Definition: trackingPlots.py:1460
h
CaloTruthAccumulator::calo_particles
Definition: CaloTruthAccumulator.cc:188
VertexProperty::VertexProperty
VertexProperty(const SimTrack *t, int c)
Definition: CaloTruthAccumulator.cc:115
DigiAccumulatorMixMod
Definition: DigiAccumulatorMixMod.h:41
HGCalGeometry
Definition: HGCalGeometry.h:29
CaloParticleCollection
std::vector< CaloParticle > CaloParticleCollection
Definition: CaloParticleFwd.h:8
CaloGeometryRecord.h
EdgeProperty::cumulative_simHits
int cumulative_simHits
Definition: CaloTruthAccumulator.cc:110
phase1PixelTopology::layer
constexpr std::array< uint8_t, layerIndexSize > layer
Definition: phase1PixelTopology.h:99
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
EncodedTruthId.h
CaloTruthAccumulator::collectionTags_
std::vector< edm::InputTag > collectionTags_
Definition: CaloTruthAccumulator.cc:174
HGCEE
Definition: ForwardSubdetector.h:8
caloTruthProducer_cfi.doHGCAL
doHGCAL
Definition: caloTruthProducer_cfi.py:12
CaloTruthAccumulator::premixStage1_
const bool premixStage1_
Definition: CaloTruthAccumulator.cc:180
CaloTruthAccumulator::messageCategory_
const std::string messageCategory_
Definition: CaloTruthAccumulator.cc:151
bphysicsOniaDQM_cfi.vertex
vertex
Definition: bphysicsOniaDQM_cfi.py:7
HGCalGeometry.h
edm::ParameterSet
Definition: ParameterSet.h:47
TrackRefitter_38T_cff.src
src
Definition: TrackRefitter_38T_cff.py:24
Event.h
tracks
const uint32_t *__restrict__ const HitContainer *__restrict__ TkSoA *__restrict__ tracks
Definition: CAHitNtupletGeneratorKernelsImpl.h:159
CaloTruthAccumulator::hgddd_
const HGCalDDDConstants * hgddd_[3]
Definition: CaloTruthAccumulator.cc:205
jetUpdater_cfi.sort
sort
Definition: jetUpdater_cfi.py:29
HcalDetId.h
CaloParticle.h
HcalTopology::dddConstants
const HcalDDDRecConstants * dddConstants() const
Definition: HcalTopology.h:164
HcalHitRelabeller.h
PCaloHit.h
HcalDetId::subdet
constexpr HcalSubdetector subdet() const
get the subdetector
Definition: HcalDetId.h:138
HcalDetId
Definition: HcalDetId.h:12
createfilelist.int
int
Definition: createfilelist.py:10
DecayChain
adjacency_list< listS, vecS, directedS, VertexMotherParticleProperty, EdgeParticleClustersProperty > DecayChain
Definition: CaloTruthAccumulator.cc:124
CaloTruthAccumulator::finalizeEvent
void finalizeEvent(edm::Event &event, const edm::EventSetup &setup) override
Definition: CaloTruthAccumulator.cc:478
trackerHitRTTI::vector
Definition: trackerHitRTTI.h:21
CaloTruthAccumulator::hepMCproductLabel_
edm::InputTag hepMCproductLabel_
Needed to add HepMC::GenVertex to SimVertex.
Definition: CaloTruthAccumulator.cc:177
edm::ProducesCollector::produces
ProductRegistryHelper::BranchAliasSetterT< ProductType > produces()
Definition: ProducesCollector.h:52
edm::EventSetup
Definition: EventSetup.h:58
SimClusterFwd.h
get
#define get
fileinputsource_cfi.sec
sec
Definition: fileinputsource_cfi.py:94
HGCalTopology
Definition: HGCalTopology.h:12
InputTag.h
CaloTruthAccumulator
Definition: CaloTruthAccumulator.cc:126
CaloTruthAccumulator::calo_particles::swap
void swap(calo_particles &oth)
Definition: CaloTruthAccumulator.cc:192
HcalHitRelabeller::relabel
DetId relabel(const uint32_t testId) const
Definition: HcalHitRelabeller.cc:49
HGCalDetId
Definition: HGCalDetId.h:8
PA_ZEESkim_cff.decay
decay
Definition: PA_ZEESkim_cff.py:26
EdgeProperty
Definition: CaloTruthAccumulator.cc:106
HGCalDetId.h
eostools.move
def move(src, dest)
Definition: eostools.py:511
edm::ProducesCollector
Definition: ProducesCollector.h:43
HltBtagValidation_cff.Vertex
Vertex
Definition: HltBtagValidation_cff.py:32
CaloTruthAccumulator::hSimTracks
edm::Handle< std::vector< SimTrack > > hSimTracks
Definition: CaloTruthAccumulator.cc:171
CaloTruthAccumulator::accumulateEvent
void accumulateEvent(const T &event, const edm::EventSetup &setup, const edm::Handle< edm::HepMCProduct > &hepMCproduct)
Both forms of accumulate() delegate to this templated method.
Definition: CaloTruthAccumulator.cc:533
CaloTruthAccumulator::geometryType_
int geometryType_
Definition: CaloTruthAccumulator.cc:210
HcalEndcap
Definition: HcalAssistant.h:34
SimTrack
Definition: SimTrack.h:9
triggerObjects_cff.id
id
Definition: triggerObjects_cff.py:29
T
long double T
Definition: Basic3DVectorLD.h:48
DetId::HGCalHSc
Definition: DetId.h:34
VertexProperty::simTrack
const SimTrack * simTrack
Definition: CaloTruthAccumulator.cc:118
CaloGeometry.h
VertexProperty
Definition: CaloTruthAccumulator.cc:113
HiBiasedCentrality_cfi.function
function
Definition: HiBiasedCentrality_cfi.py:4
EdgeProperty::simHits
int simHits
Definition: CaloTruthAccumulator.cc:109
EventSetup.h
or
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
CaloTruthAccumulator::doHGCAL
bool doHGCAL
Definition: CaloTruthAccumulator.cc:211
IfLogDebug
#define IfLogDebug(cond, cat)
Definition: MessageLogger.h:259
triggerMatcherToHLTDebug_cfi.tags
tags
Definition: triggerMatcherToHLTDebug_cfi.py:9
filterCSVwithJSON.target
target
Definition: filterCSVwithJSON.py:32
HcalDDDRecConstants
Definition: HcalDDDRecConstants.h:23
EdgeProperty::EdgeProperty
EdgeProperty(const SimTrack *t, int h, int c)
Definition: CaloTruthAccumulator.cc:107
CaloTruthAccumulator::hcddd_
const HcalDDDRecConstants * hcddd_
Definition: CaloTruthAccumulator.cc:206
CaloTruthAccumulator::simTrackLabel_
const edm::InputTag simTrackLabel_
Definition: CaloTruthAccumulator.cc:169
math::Graph< DDLogicalPart, DDPosData * >
HGCHEF
Definition: ForwardSubdetector.h:9
ConsumesCollector.h
DigiAccumulatorMixModFactory.h
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
HcalGeometry::topology
const HcalTopology & topology() const
Definition: HcalGeometry.h:111
CaloTruthAccumulator::m_caloParticles
calo_particles m_caloParticles
Definition: CaloTruthAccumulator.cc:208
ParameterSet.h
DEFINE_DIGI_ACCUMULATOR
#define DEFINE_DIGI_ACCUMULATOR(type)
Definition: DigiAccumulatorMixModFactory.h:31
HepMCProduct.h
c
auto & c
Definition: CAHitNtupletGeneratorKernelsImpl.h:46
dqmiolumiharvest.j
j
Definition: dqmiolumiharvest.py:66
DetId::Forward
Definition: DetId.h:30
event
Definition: event.py:1
hltrates_dqm_sourceclient-live_cfg.offset
offset
Definition: hltrates_dqm_sourceclient-live_cfg.py:82
edm::Event
Definition: Event.h:73
submitPVValidationJobs.t
string t
Definition: submitPVValidationJobs.py:644
lumi
Definition: LumiSectionData.h:20
VertexProperty::VertexProperty
VertexProperty()
Definition: CaloTruthAccumulator.cc:114
HcalGeometry
Definition: HcalGeometry.h:17
StripSubdetector.h
edm::InputTag
Definition: InputTag.h:15
edm::ConsumesCollector
Definition: ConsumesCollector.h:45
g
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
VertexProperty::VertexProperty
VertexProperty(const VertexProperty &other)
Definition: CaloTruthAccumulator.cc:116
EdgeProperty::simTrack
const SimTrack * simTrack
Definition: CaloTruthAccumulator.cc:108
findQualityFiles.size
size
Write out results.
Definition: findQualityFiles.py:443
pwdgSkimBPark_cfi.vertices
vertices
Definition: pwdgSkimBPark_cfi.py:7
MillePedeFileConverter_cfg.e
e
Definition: MillePedeFileConverter_cfg.py:37
HGCalTestNumbering.h
CaloTruthAccumulator::genParticleLabel_
edm::InputTag genParticleLabel_
Definition: CaloTruthAccumulator.cc:175