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