CMS 3D CMS Logo

List of all members | Classes | Public Member Functions | Private Member Functions | Private Attributes
MtdTruthAccumulator Class Reference
Inheritance diagram for MtdTruthAccumulator:
DigiAccumulatorMixMod

Classes

struct  calo_particles
 
struct  OutputCollections
 

Public Member Functions

 MtdTruthAccumulator (const edm::ParameterSet &config, edm::ProducesCollector, edm::ConsumesCollector &iC)
 
- Public Member Functions inherited from DigiAccumulatorMixMod
virtual void beginLuminosityBlock (edm::LuminosityBlock const &lumi, edm::EventSetup const &setup)
 
virtual void beginRun (edm::Run const &run, edm::EventSetup const &setup)
 
 DigiAccumulatorMixMod ()
 
 DigiAccumulatorMixMod (DigiAccumulatorMixMod const &)=delete
 
virtual void endLuminosityBlock (edm::LuminosityBlock const &lumi, edm::EventSetup const &setup)
 
virtual void endRun (edm::Run const &run, edm::EventSetup const &setup)
 
virtual void finalizeBunchCrossing (edm::Event &event, edm::EventSetup const &setup, int bunchCrossing)
 
virtual PileupMixingContentgetEventPileupInfo ()
 
virtual void initializeBunchCrossing (edm::Event const &event, edm::EventSetup const &setup, int bunchCrossing)
 
DigiAccumulatorMixMod const & operator= (DigiAccumulatorMixMod const &)=delete
 
virtual void StorePileupInformation (std::vector< int > &numInteractionList, std::vector< int > &bunchCrossingList, std::vector< float > &TrueInteractionList, std::vector< edm::EventID > &eventList, int bunchSpace)
 
virtual ~DigiAccumulatorMixMod ()
 

Private Member Functions

void accumulate (const edm::Event &event, const edm::EventSetup &setup) override
 
void accumulate (const PileUpEventPrincipal &event, const edm::EventSetup &setup, edm::StreamID const &) override
 
template<class T >
void accumulateEvent (const T &event, const edm::EventSetup &setup, const edm::Handle< edm::HepMCProduct > &hepMCproduct)
 Both forms of accumulate() delegate to this templated method. More...
 
template<class T >
void fillSimHits (std::vector< std::pair< uint64_t, const PSimHit *>> &returnValue, std::unordered_map< int, std::map< uint64_t, float >> &simTrackDetIdEnergyMap, std::unordered_map< int, std::map< uint64_t, float >> &simTrackDetIdTimeMap, const T &event, const edm::EventSetup &setup)
 Fills the supplied vector with pointers to the SimHits, checking for bad modules if required. More...
 
void finalizeEvent (edm::Event &event, const edm::EventSetup &setup) override
 
void initializeEvent (const edm::Event &event, const edm::EventSetup &setup) override
 

Private Attributes

const unsigned int bunchSpacing_
 
std::vector< edm::InputTagcollectionTags_
 
edm::InputTag genParticleLabel_
 
const MTDGeometrygeom = nullptr
 
const edm::ESGetToken< MTDGeometry, MTDDigiGeometryRecordgeomToken_
 
mtd::MTDGeomUtil geomTools_
 
edm::InputTag hepMCproductLabel_
 Needed to add HepMC::GenVertex to SimVertex. More...
 
edm::Handle< std::vector< SimTrack > > hSimTracks
 
edm::Handle< std::vector< SimVertex > > hSimVertices
 
bool isEtl_
 
calo_particles m_caloParticles
 
std::unordered_map< uint64_t, float > m_detIdToTotalSimEnergy
 
std::unordered_multimap< Barcode_t, Index_t > m_simHitBarcodeToIndex
 
const unsigned int maximumPreviousBunchCrossing_
 
const unsigned int maximumSubsequentBunchCrossing_
 
const double maxPseudoRapidity_
 
const std::string messageCategory_
 
const double minEnergy_
 
const edm::ESGetToken< MTDTopology, MTDTopologyRcdmtdtopoToken_
 
OutputCollections output_
 
const bool premixStage1_
 
const edm::InputTag simTrackLabel_
 
const edm::InputTag simVertexLabel_
 
const MTDTopologytopology = nullptr
 

Detailed Description

Definition at line 66 of file MtdTruthAccumulator.cc.

Constructor & Destructor Documentation

◆ MtdTruthAccumulator()

MtdTruthAccumulator::MtdTruthAccumulator ( const edm::ParameterSet config,
edm::ProducesCollector  producesCollector,
edm::ConsumesCollector iC 
)
explicit

Definition at line 245 of file MtdTruthAccumulator.cc.

References collectionTags_, edm::ConsumesCollector::consumes(), genParticleLabel_, hepMCproductLabel_, isEtl_, premixStage1_, edm::ProducesCollector::produces(), simTrackLabel_, simVertexLabel_, and triggerMatcherToHLTDebug_cfi::tags.

248  : messageCategory_("MtdTruthAccumulator"),
249  maximumPreviousBunchCrossing_(config.getParameter<unsigned int>("maximumPreviousBunchCrossing")),
250  maximumSubsequentBunchCrossing_(config.getParameter<unsigned int>("maximumSubsequentBunchCrossing")),
251  bunchSpacing_(config.getParameter<unsigned int>("bunchspace")),
252  simTrackLabel_(config.getParameter<edm::InputTag>("simTrackCollection")),
253  simVertexLabel_(config.getParameter<edm::InputTag>("simVertexCollection")),
254  collectionTags_(),
255  genParticleLabel_(config.getParameter<edm::InputTag>("genParticleCollection")),
256  hepMCproductLabel_(config.getParameter<edm::InputTag>("HepMCProductLabel")),
259  minEnergy_(config.getParameter<double>("MinEnergy")),
260  maxPseudoRapidity_(config.getParameter<double>("MaxPseudoRapidity")),
261  premixStage1_(config.getParameter<bool>("premixStage1")) {
262  iC.consumes<std::vector<SimTrack>>(simTrackLabel_);
263  iC.consumes<std::vector<SimVertex>>(simVertexLabel_);
264  iC.consumes<std::vector<reco::GenParticle>>(genParticleLabel_);
265  iC.consumes<std::vector<int>>(genParticleLabel_);
266  iC.consumes<std::vector<int>>(hepMCproductLabel_);
267 
268  // Fill the collection tags
269  const edm::ParameterSet &simHitCollectionConfig = config.getParameterSet("simHitCollections");
270  std::vector<std::string> parameterNames = simHitCollectionConfig.getParameterNames();
271 
272  for (auto const &parameterName : parameterNames) {
273  std::vector<edm::InputTag> tags = simHitCollectionConfig.getParameter<std::vector<edm::InputTag>>(parameterName);
274  collectionTags_.insert(collectionTags_.end(), tags.begin(), tags.end());
275  }
276 
277  for (auto const &collectionTag : collectionTags_) {
278  iC.consumes<std::vector<PSimHit>>(collectionTag);
279  isEtl_ = (collectionTag.instance().find("FastTimerHitsEndcap") != std::string::npos);
280  }
281 
282  producesCollector.produces<MtdSimClusterCollection>("MergedMtdTruth");
283  producesCollector.produces<MtdSimLayerClusterCollection>("MergedMtdTruthLC");
284  producesCollector.produces<MtdSimTracksterCollection>("MergedMtdTruthST");
285  producesCollector.produces<MtdCaloParticleCollection>("MergedMtdTruth");
286  if (premixStage1_) {
287  producesCollector.produces<std::vector<std::pair<uint64_t, float>>>("MergedMtdTruth");
288  }
289 }
std::vector< MtdSimLayerCluster > MtdSimLayerClusterCollection
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
const edm::ESGetToken< MTDTopology, MTDTopologyRcd > mtdtopoToken_
const edm::InputTag simVertexLabel_
std::vector< MtdCaloParticle > MtdCaloParticleCollection
ProductRegistryHelper::BranchAliasSetterT< ProductType > produces()
edm::InputTag genParticleLabel_
const edm::InputTag simTrackLabel_
const edm::ESGetToken< MTDGeometry, MTDDigiGeometryRecord > geomToken_
const std::string messageCategory_
const unsigned int maximumSubsequentBunchCrossing_
Definition: config.py:1
const unsigned int bunchSpacing_
const unsigned int maximumPreviousBunchCrossing_
std::vector< edm::InputTag > collectionTags_
std::vector< MtdSimCluster > MtdSimClusterCollection
std::vector< MtdSimTrackster > MtdSimTracksterCollection
edm::InputTag hepMCproductLabel_
Needed to add HepMC::GenVertex to SimVertex.

Member Function Documentation

◆ accumulate() [1/2]

void MtdTruthAccumulator::accumulate ( const edm::Event event,
const edm::EventSetup setup 
)
overrideprivatevirtual

Create handle to edm::HepMCProduct here because event.getByLabel with edm::HepMCProduct only works for edm::Event but not for PileUpEventPrincipal; PileUpEventPrincipal::getByLabel tries to call T::value_type and T::iterator (where T is the type of the object one wants to get a handle to) which is only implemented for container-like objects like std::vector but not for edm::HepMCProduct!

Implements DigiAccumulatorMixMod.

Definition at line 317 of file MtdTruthAccumulator.cc.

References accumulateEvent(), hepMCproductLabel_, messageCategory_, and singleTopDQM_cfi::setup.

317  {
319  event.getByLabel(hepMCproductLabel_, hepmc);
320 
321  edm::LogInfo(messageCategory_) << " MtdTruthAccumulator::accumulate (signal)";
322  accumulateEvent(event, setup, hepmc);
323 }
const std::string messageCategory_
void accumulateEvent(const T &event, const edm::EventSetup &setup, const edm::Handle< edm::HepMCProduct > &hepMCproduct)
Both forms of accumulate() delegate to this templated method.
Log< level::Info, false > LogInfo
edm::InputTag hepMCproductLabel_
Needed to add HepMC::GenVertex to SimVertex.
Definition: event.py:1

◆ accumulate() [2/2]

void MtdTruthAccumulator::accumulate ( const PileUpEventPrincipal event,
const edm::EventSetup setup,
edm::StreamID const &   
)
overrideprivatevirtual

Implements DigiAccumulatorMixMod.

Definition at line 325 of file MtdTruthAccumulator.cc.

References accumulateEvent(), maximumPreviousBunchCrossing_, maximumSubsequentBunchCrossing_, messageCategory_, and singleTopDQM_cfi::setup.

327  {
328  if (event.bunchCrossing() >= -static_cast<int>(maximumPreviousBunchCrossing_) &&
329  event.bunchCrossing() <= static_cast<int>(maximumSubsequentBunchCrossing_)) {
330  // simply create empty handle as we do not have a HepMCProduct in PU anyway
332  edm::LogInfo(messageCategory_) << " MtdTruthAccumulator::accumulate (pileup) bunchCrossing="
333  << event.bunchCrossing();
334  accumulateEvent(event, setup, hepmc);
335  } else {
336  edm::LogInfo(messageCategory_) << "Skipping pileup event for bunch crossing " << event.bunchCrossing();
337  }
338 }
const std::string messageCategory_
const unsigned int maximumSubsequentBunchCrossing_
void accumulateEvent(const T &event, const edm::EventSetup &setup, const edm::Handle< edm::HepMCProduct > &hepMCproduct)
Both forms of accumulate() delegate to this templated method.
const unsigned int maximumPreviousBunchCrossing_
Log< level::Info, false > LogInfo
Definition: event.py:1

◆ accumulateEvent()

template<class T >
void MtdTruthAccumulator::accumulateEvent ( const T event,
const edm::EventSetup setup,
const edm::Handle< edm::HepMCProduct > &  hepMCproduct 
)
private

Both forms of accumulate() delegate to this templated method.


Build the main decay graph and assign the SimTrack to each edge. The graph built here will only contain the particles that have a decay vertex associated to them. In order to recover also the particles that will not decay, we need to keep track of the SimTrack used here and add, a-posteriori, the ones not used, associating a ghost vertex (starting from the highest simulated vertex number), in order to build the edge and identify them immediately as stable (i.e. not decayed).

To take into account the multi-bremsstrahlung effects in which a single particle is emitting photons in different vertices keeping the same track index, we also collapsed those vertices into 1 unique vertex. The other approach of fully representing the decay chain keeping the same track index would have the problem of over-counting the contributions of that track, especially in terms of hits.

The 2 auxiliary vectors are structured as follow:

  1. used_sim_tracks is a vector that has the same size as the overall number of simulated tracks. The associated integer is the vertexId of the decaying vertex for that track.
  2. collapsed_vertices is a vector that has the same size as the overall number of simulated vertices. The vector's index is the vertexId itself, the associated value is the vertexId of the vertex on which this should collapse.

Definition at line 573 of file MtdTruthAccumulator.cc.

References funct::abs(), bunchSpacing_, gather_cfg::cout, EdgeProperty::cumulative_simHits, DEBUG, PA_ZEESkim_cff::decay, fillSimHits(), genParticleLabel_, hSimTracks, hSimVertices, mps_fire::i, heavyIonCSV_trainingSettings::idx, IfLogDebug, m_caloParticles, m_simHitBarcodeToIndex, maxPseudoRapidity_, messageCategory_, minEnergy_, CoreSimTrack::momentum(), SimTrack::noGenpart(), hltrates_dqm_sourceclient-live_cfg::offset, output_, put(), edm::second(), singleTopDQM_cfi::setup, EdgeProperty::simTrack, simTrackLabel_, simVertexLabel_, findQualityFiles::size, submitPVValidationJobs::t, DiMuonV_cfg::tracks, findQualityFiles::v, AlignmentTracksFromVertexSelector_cfi::vertices, and runTauDisplay::vis.

Referenced by accumulate().

575  {
577  edm::Handle<std::vector<int>> hGenParticleIndices;
578 
579  event.getByLabel(simTrackLabel_, hSimTracks);
580  event.getByLabel(simVertexLabel_, hSimVertices);
581 
582  event.getByLabel(genParticleLabel_, hGenParticles);
583  event.getByLabel(genParticleLabel_, hGenParticleIndices);
584 
585  std::vector<std::pair<uint64_t, const PSimHit *>> simHitPointers;
586  std::unordered_map<int, std::map<uint64_t, float>> simTrackDetIdEnergyMap;
587  std::unordered_map<int, std::map<uint64_t, float>> simTrackDetIdTimeMap;
588  fillSimHits(simHitPointers, simTrackDetIdEnergyMap, simTrackDetIdTimeMap, event, setup);
589 
590  // Clear maps from previous event fill them for this one
591  m_simHitBarcodeToIndex.clear();
592  for (unsigned int i = 0; i < simHitPointers.size(); ++i) {
593  m_simHitBarcodeToIndex.emplace(simHitPointers[i].second->trackId(), i);
594  }
595 
596  auto const &tracks = *hSimTracks;
597  auto const &vertices = *hSimVertices;
598  std::unordered_map<int, int> trackid_to_track_index;
599  std::unordered_map<uint32_t, float> vertex_time_map;
601 
602  for (uint32_t i = 0; i < vertices.size(); i++) {
603  vertex_time_map[i] = vertices[i].position().t() * 1e9 + event.bunchCrossing() * bunchSpacing_;
604  }
605 
606  IfLogDebug(DEBUG, messageCategory_) << " TRACKS" << std::endl;
607  int idx = 0;
608  for (auto const &t : tracks) {
609  IfLogDebug(DEBUG, messageCategory_) << " " << idx << "\t" << t.trackId() << "\t" << t << std::endl;
610  trackid_to_track_index[t.trackId()] = idx;
611  idx++;
612  }
613 
640  idx = 0;
641  std::vector<int> used_sim_tracks(tracks.size(), 0);
642  std::vector<int> collapsed_vertices(vertices.size(), 0);
643  IfLogDebug(DEBUG, messageCategory_) << " VERTICES" << std::endl;
644  for (auto const &v : vertices) {
645  IfLogDebug(DEBUG, messageCategory_) << " " << idx++ << "\t" << v << std::endl;
646  if (v.parentIndex() != -1) {
647  auto const trk_idx = trackid_to_track_index[v.parentIndex()];
648  auto origin_vtx = tracks[trk_idx].vertIndex();
649  if (used_sim_tracks[trk_idx]) {
650  // collapse the vertex into the original first vertex we saw associated
651  // to this track. Omit adding the edge in order to avoid double
652  // counting of the very same particles and its associated hits.
653  collapsed_vertices[v.vertexId()] = used_sim_tracks[trk_idx];
654  continue;
655  }
656  // Perform the actual vertex collapsing, if needed.
657  if (collapsed_vertices[origin_vtx])
658  origin_vtx = collapsed_vertices[origin_vtx];
659  add_edge(origin_vtx,
660  v.vertexId(),
661  EdgeProperty(&tracks[trk_idx], simTrackDetIdEnergyMap[v.parentIndex()].size(), 0),
662  decay);
663  used_sim_tracks[trk_idx] = v.vertexId();
664  }
665  }
666  // Build the motherParticle property to each vertex
667  auto const &vertexMothersProp = get(vertex_name, decay);
668  // Now recover the particles that did not decay. Append them with an index
669  // bigger than the size of the generated vertices.
670  int offset = vertices.size();
671  for (size_t i = 0; i < tracks.size(); ++i) {
672  if (!used_sim_tracks[i]) {
673  auto origin_vtx = tracks[i].vertIndex();
674  // Perform the actual vertex collapsing, if needed.
675  if (collapsed_vertices[origin_vtx])
676  origin_vtx = collapsed_vertices[origin_vtx];
677  add_edge(
678  origin_vtx, offset, EdgeProperty(&tracks[i], simTrackDetIdEnergyMap[tracks[i].trackId()].size(), 0), decay);
679  // The properties for "fake" vertices associated to stable particles have
680  // to be set inside this loop, since they do not belong to the vertices
681  // collection and would be skipped by that loop (coming next)
682  put(vertexMothersProp, offset, VertexProperty(&tracks[i], 0));
683  offset++;
684  }
685  }
686  for (auto const &v : vertices) {
687  if (v.parentIndex() != -1) {
688  // Skip collapsed_vertices
689  if (collapsed_vertices[v.vertexId()])
690  continue;
691  put(vertexMothersProp, v.vertexId(), VertexProperty(&tracks[trackid_to_track_index[v.parentIndex()]], 0));
692  }
693  }
694  SimHitsAccumulator_dfs_visitor vis;
695  depth_first_search(decay, visitor(vis));
696  CaloParticle_dfs_visitor caloParticleCreator(
697  output_,
700  simTrackDetIdEnergyMap,
701  simTrackDetIdTimeMap,
702  vertex_time_map,
703  [&](EdgeProperty &edge_property) -> bool {
704  // Apply selection on SimTracks in order to promote them to be
705  // CaloParticles. The function returns TRUE if the particle satisfies
706  // the selection, FALSE otherwise. Therefore the correct logic to select
707  // the particle is to ask for TRUE as return value.
708  return (edge_property.cumulative_simHits != 0 and !edge_property.simTrack->noGenpart() and
709  edge_property.simTrack->momentum().E() > minEnergy_ and
710  std::abs(edge_property.simTrack->momentum().Eta()) < maxPseudoRapidity_);
711  });
712  depth_first_search(decay, visitor(caloParticleCreator));
713 
714 #if DEBUG
715  boost::write_graphviz(std::cout,
716  decay,
717  make_label_writer(make_transform_value_property_map(&graphviz_vertex, get(vertex_name, decay))),
718  make_label_writer(make_transform_value_property_map(&graphviz_edge, get(edge_weight, decay))));
719 #endif
720 }
size
Write out results.
const edm::InputTag simVertexLabel_
edm::InputTag genParticleLabel_
const edm::InputTag simTrackLabel_
const std::string messageCategory_
#define DEBUG
void fillSimHits(std::vector< std::pair< uint64_t, const PSimHit *>> &returnValue, std::unordered_map< int, std::map< uint64_t, float >> &simTrackDetIdEnergyMap, std::unordered_map< int, std::map< uint64_t, float >> &simTrackDetIdTimeMap, const T &event, const edm::EventSetup &setup)
Fills the supplied vector with pointers to the SimHits, checking for bad modules if required...
const unsigned int bunchSpacing_
const math::XYZTLorentzVectorD & momentum() const
Definition: CoreSimTrack.h:19
void put(edm::Event &evt, double value, const char *instanceName)
const SimTrack * simTrack
Definition: DecayGraph.h:61
U second(std::pair< T, U > const &p)
#define IfLogDebug(cond, cat)
adjacency_list< listS, vecS, directedS, VertexMotherParticleProperty, EdgeParticleClustersProperty > DecayChain
Definition: DecayGraph.h:77
int cumulative_simHits
Definition: DecayGraph.h:63
std::unordered_multimap< Barcode_t, Index_t > m_simHitBarcodeToIndex
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
OutputCollections output_
calo_particles m_caloParticles
edm::Handle< std::vector< SimVertex > > hSimVertices
bool noGenpart() const
Definition: SimTrack.h:38
edm::Handle< std::vector< SimTrack > > hSimTracks
Definition: event.py:1

◆ fillSimHits()

template<class T >
void MtdTruthAccumulator::fillSimHits ( std::vector< std::pair< uint64_t, const PSimHit *>> &  returnValue,
std::unordered_map< int, std::map< uint64_t, float >> &  simTrackDetIdEnergyMap,
std::unordered_map< int, std::map< uint64_t, float >> &  simTrackDetIdTimeMap,
const T event,
const edm::EventSetup setup 
)
private

Fills the supplied vector with pointers to the SimHits, checking for bad modules if required.

Definition at line 723 of file MtdTruthAccumulator.cc.

References collectionTags_, angle_units::operators::convertMmToCm(), geant_units::operators::convertUnitsTo(), DEBUG, geomTools_, mtd::MTDGeomUtil::globalPosition(), l1ctLayer2EG_cff::id, IfLogDebug, createfilelist::int, mtd::MTDGeomUtil::layer(), m_detIdToTotalSimEnergy, messageCategory_, mtd::MTDGeomUtil::module(), muonClassificationByHits_cfi::pixel, mtd::MTDGeomUtil::pixelInModule(), position, and rpcPointValidation_cfi::simHit.

Referenced by accumulateEvent().

727  {
728  using namespace geant_units::operators;
729  using namespace angle_units::operators;
730  for (auto const &collectionTag : collectionTags_) {
732  event.getByLabel(collectionTag, hSimHits);
733 
734  for (auto const &simHit : *hSimHits) {
735  DetId id(0);
736 
737  // --- Use only hits compatible with the in-time bunch-crossing
738  if (simHit.tof() < 0 || simHit.tof() > 25.)
739  continue;
740 
741  id = simHit.detUnitId();
742 
743  if (id == DetId(0)) {
744  edm::LogWarning(messageCategory_) << "Invalid DetId for the current simHit!";
745  continue;
746  }
747 
748  if (simHit.trackId() == 0) {
749  continue;
750  }
751 
752  returnValue.emplace_back(id, &simHit);
753 
754  // get an unique id: for BTL the detId is unique (one for each crystal), for ETL the detId is not enough
755  // also row and column are needed. An unique number is created from detId, row, col
756  // Get row and column
757  const auto &position = simHit.localPosition();
759  std::pair<uint8_t, uint8_t> pixel = geomTools_.pixelInModule(id, simscaled);
760  // create the unique id
761  uint64_t uniqueId = static_cast<uint64_t>(id.rawId()) << 32;
762  uniqueId |= pixel.first << 16;
763  uniqueId |= pixel.second;
764 
765  simTrackDetIdEnergyMap[simHit.trackId()][uniqueId] += simHit.energyLoss();
766  m_detIdToTotalSimEnergy[uniqueId] += simHit.energyLoss();
767  // --- Get the time of the first SIM hit in the cell
768  if (simTrackDetIdTimeMap[simHit.trackId()][uniqueId] == 0. ||
769  simHit.tof() < simTrackDetIdTimeMap[simHit.trackId()][uniqueId]) {
770  simTrackDetIdTimeMap[simHit.trackId()][uniqueId] = simHit.tof();
771  }
772 
773 #ifdef PRINT_DEBUG
775  << "hitId " << id.rawId() << " from track " << simHit.trackId() << " in layer " << geomTools_.layer(id)
776  << ", module " << geomTools_.module(id) << ", pixel ( " << (int)geomTools_.pixelInModule(id, simscaled).first
777  << ", " << (int)geomTools_.pixelInModule(id, simscaled).second << " )\n global pos(cm) "
778  << geomTools_.globalPosition(id, simscaled) << ", time(ns) " << simHit.tof() << ", energy(MeV) "
779  << convertUnitsTo(0.001_MeV, simHit.energyLoss()) << std::endl;
780 #endif
781  } // end of loop over simHits
782  } // end of loop over InputTags
783 }
GlobalPoint globalPosition(const DetId &id, const LocalPoint &local_point) const
Definition: MTDGeomUtil.cc:58
std::pair< float, float > pixelInModule(const DetId &id, const int row, const int column) const
Definition: MTDGeomUtil.cc:111
const std::string messageCategory_
#define DEBUG
constexpr NumType convertUnitsTo(double desiredUnits, NumType val)
Definition: GeantUnits.h:73
#define IfLogDebug(cond, cat)
unsigned int layer(const DetId &) const
Definition: MTDGeomUtil.cc:89
Definition: DetId.h:17
constexpr NumType convertMmToCm(NumType millimeters)
Definition: angle_units.h:44
unsigned long long uint64_t
Definition: Time.h:13
std::vector< edm::InputTag > collectionTags_
std::unordered_map< uint64_t, float > m_detIdToTotalSimEnergy
static int position[264][3]
Definition: ReadPGInfo.cc:289
int module(const DetId &) const
Definition: MTDGeomUtil.cc:98
Log< level::Warning, false > LogWarning
mtd::MTDGeomUtil geomTools_

◆ finalizeEvent()

void MtdTruthAccumulator::finalizeEvent ( edm::Event event,
const edm::EventSetup setup 
)
overrideprivatevirtual

Implements DigiAccumulatorMixMod.

Definition at line 340 of file MtdTruthAccumulator.cc.

References a, b, geant_units::operators::convertUnitsTo(), filterCSVwithJSON::copy, DEBUG, hcalRecHitTable_cff::energy, dqmdumpme::first, alignBH_cfg::fixed, HLT_2024v13_cff::fraction, geomTools_, mps_fire::i, l1ctLayer2EG_cff::id, IfLogDebug, dqmdumpme::indices, createfilelist::int, mtd::MTDGeomUtil::isETL(), dqmiolumiharvest::j, mtd::MTDGeomUtil::layer(), m_caloParticles, m_detIdToTotalSimEnergy, m_simHitBarcodeToIndex, messageCategory_, mtd::MTDGeomUtil::module(), eostools::move(), or, output_, MtdTruthAccumulator::OutputCollections::pCaloParticles, MtdTruthAccumulator::OutputCollections::pMtdSimLayerClusters, MtdTruthAccumulator::OutputCollections::pMtdSimTracksters, mtd::MTDGeomUtil::position(), position, premixStage1_, MtdTruthAccumulator::OutputCollections::pSimClusters, MtdTruthAccumulator::calo_particles::sc_start_, MtdTruthAccumulator::calo_particles::sc_stop_, edm::second(), jetUpdater_cfi::sort, edm::swap(), and MtdTruthAccumulator::calo_particles::swap().

340  {
341  using namespace geant_units::operators;
342 
343  edm::LogInfo(messageCategory_) << "Adding " << output_.pSimClusters->size() << " SimParticles and "
344  << output_.pCaloParticles->size() << " CaloParticles to the event.";
345 
346  // We need to normalize the hits and energies into hits and fractions (since
347  // we have looped over all pileup events)
348  // For premixing stage1 we keep the energies, they will be normalized to
349  // fractions in stage2
350 
351  if (premixStage1_) {
352  auto totalEnergies = std::make_unique<std::vector<std::pair<uint64_t, float>>>();
353  totalEnergies->reserve(m_detIdToTotalSimEnergy.size());
354  std::copy(m_detIdToTotalSimEnergy.begin(), m_detIdToTotalSimEnergy.end(), std::back_inserter(*totalEnergies));
355  std::sort(totalEnergies->begin(), totalEnergies->end());
356  event.put(std::move(totalEnergies), "MergedMtdTruth");
357  } else {
358  for (auto &sc : *(output_.pSimClusters)) {
359  auto hitsAndEnergies = sc.hits_and_fractions();
360  sc.clearHitsAndFractions();
361  sc.clearHitsEnergy();
362  for (auto &hAndE : hitsAndEnergies) {
363  const float totalenergy = m_detIdToTotalSimEnergy[hAndE.first];
364  float fraction = 0.;
365  if (totalenergy > 0)
366  fraction = hAndE.second / totalenergy;
367  else
369  << "TotalSimEnergy for hit " << hAndE.first << " is 0! The fraction for this hit cannot be computed.";
370  sc.addHitAndFraction(hAndE.first, fraction);
371  sc.addHitEnergy(hAndE.second);
372  }
373  }
374  }
375 
376 #ifdef PRINT_DEBUG
377  IfLogDebug(DEBUG, messageCategory_) << "SIMCLUSTERS LIST:" << std::endl;
378  for (const auto &sc : *(output_.pSimClusters)) {
379  IfLogDebug(DEBUG, messageCategory_) << std::fixed << std::setprecision(3) << "SimCluster from CP with:"
380  << "\n charge " << sc.charge() << "\n pdgId " << sc.pdgId() << "\n energy "
381  << sc.energy() << " GeV\n eta " << sc.eta() << "\n phi " << sc.phi()
382  << "\n number of cells = " << sc.hits_and_fractions().size() << std::endl;
383  for (unsigned int i = 0; i < sc.hits_and_fractions().size(); ++i) {
384  DetId id(sc.detIds_and_rows()[i].first);
386  << std::fixed << std::setprecision(3) << " hit " << id.rawId() << " on layer " << geomTools_.layer(id)
387  << " module " << geomTools_.module(id) << " row " << (unsigned int)(sc.detIds_and_rows()[i].second).first
388  << " col " << (unsigned int)(sc.detIds_and_rows()[i].second).second << " at time "
389  << sc.hits_and_times()[i].second << " ns" << std::endl;
390  }
391  IfLogDebug(DEBUG, messageCategory_) << "--------------\n";
392  }
393  IfLogDebug(DEBUG, messageCategory_) << std::endl;
394 #endif
395 
396  // save the SimCluster orphan handle so we can fill the calo particles
397  auto scHandle = event.put(std::move(output_.pSimClusters), "MergedMtdTruth");
398 
399  // reserve for the best case scenario: already splitted
400  output_.pMtdSimLayerClusters->reserve(scHandle->size());
401  output_.pMtdSimTracksters->reserve(scHandle->size());
402 
403  uint32_t SC_index = 0;
404  uint32_t LC_index = 0;
405  for (const auto &sc : *scHandle) {
406  auto const &hAndF = sc.hits_and_fractions();
407  auto const &hAndE = sc.hits_and_energies();
408  auto const &hAndT = sc.hits_and_times();
409  auto const &hAndR = sc.detIds_and_rows();
410  // create a vector with the indices of the hits in the simCluster
411  std::vector<int> indices(hAndF.size());
412  std::iota(indices.begin(), indices.end(), 0);
413  // sort the hits indices based on the unique indices created before
414  std::sort(indices.begin(), indices.end(), [&](int a, int b) { return hAndF[a].first < hAndF[b].first; });
415 
416  // now split the sc: loop on the sorted indices and save the first hit in a
417  // temporary simCluster. If the following hit is in the same module and row (column),
418  // but next column (row) put it in the temporary simcluster as well, otherwise
419  // put the temporary simcluster in the collection and start creating a new one
420  std::vector<uint32_t> LC_indices;
421  MtdSimLayerCluster tmpLC(sc.g4Tracks()[0]);
422  int prev = indices[0];
423  DetId prevId(hAndR[prev].first);
424 
425  float SimLCenergy = 0.;
426  float SimLCx = 0., SimLCy = 0., SimLCz = 0.;
427 
428  auto push_back_hit = [&](const int &ind) {
429  tmpLC.addHitAndFraction(hAndF[ind].first, hAndF[ind].second);
430  tmpLC.addHitEnergy(hAndE[ind].second);
431  tmpLC.addHitTime(hAndT[ind].second);
432  };
433 
434  auto update_clu_info = [&](const int &ind) {
435  double energy = hAndE[ind].second;
436  auto position =
437  geomTools_.position((DetId)hAndR[ind].first, (hAndR[ind].second).first, (hAndR[ind].second).second).first;
438  SimLCenergy += energy;
439  SimLCx += position.x() * energy;
440  SimLCy += position.y() * energy;
441  SimLCz += position.z() * energy;
442  };
443 
444  auto push_back_clu = [&](const uint32_t &SC_index, uint32_t &LC_index) {
445  tmpLC.addCluEnergy(SimLCenergy);
446  LocalPoint SimLCpos(SimLCx / SimLCenergy, SimLCy / SimLCenergy, SimLCz / SimLCenergy);
447  tmpLC.addCluLocalPos(SimLCpos);
448  SimLCenergy = 0.;
449  SimLCx = 0.;
450  SimLCy = 0.;
451  SimLCz = 0.;
452  tmpLC.addCluIndex(SC_index);
453  tmpLC.computeClusterTime();
454  output_.pMtdSimLayerClusters->push_back(tmpLC);
455  LC_indices.push_back(LC_index);
456  LC_index++;
457  tmpLC.clear();
458  };
459 
460  // fill tmpLC with the first hit
461  push_back_hit(prev);
462  update_clu_info(prev);
463  for (const auto &ind : indices) {
464  if (ind == indices[0])
465  continue;
466  DetId id(hAndR[ind].first);
467  if (geomTools_.isETL(id) != geomTools_.isETL(prevId) or geomTools_.layer(id) != geomTools_.layer(prevId) or
468  geomTools_.module(id) != geomTools_.module(prevId) or
469  ((hAndR[ind].second).first == (hAndR[prev].second).first and
470  (hAndR[ind].second).second != (hAndR[prev].second).second + 1) or
471  ((hAndR[ind].second).second == (hAndR[prev].second).second and
472  (hAndR[ind].second).first != (hAndR[prev].second).first + 1)) {
473  // the next hit is not adjacent to the previous one, put the current temporary cluster in the collection
474  // and the hit will be put in an empty temporary cluster
475  push_back_clu(SC_index, LC_index);
476  }
477  // add the hit to the temporary cluster
478  push_back_hit(ind);
479  update_clu_info(ind);
480  prev = ind;
481  DetId newId(hAndR[prev].first);
482  prevId = newId;
483  }
484  // add the remaining temporary cluster to the collection
485  push_back_clu(SC_index, LC_index);
486 
487  // now the simTrackster: find position and time of the first simHit
488  // bc right now there is no method to ask the simTrack for pos/time
489  // at MTD entrance
490  float timeAtEntrance = 99.;
491  uint32_t idAtEntrance = 0;
492  for (uint32_t i = 0; i < (uint32_t)hAndT.size(); i++) {
493  if (hAndT[i].second < timeAtEntrance) {
494  timeAtEntrance = hAndT[i].second;
495  idAtEntrance = i;
496  }
497  }
498 
499  // sort LCs in the SimTrackster by time
500  auto &MtdSimLayerClusters = output_.pMtdSimLayerClusters;
501  std::sort(LC_indices.begin(), LC_indices.end(), [&MtdSimLayerClusters](int i, int j) {
502  return (*MtdSimLayerClusters)[i].simLCTime() < (*MtdSimLayerClusters)[j].simLCTime();
503  });
504 
505  GlobalPoint posAtEntrance = geomTools_
506  .position((DetId)hAndR[idAtEntrance].first,
507  (hAndR[idAtEntrance].second).first,
508  (hAndR[idAtEntrance].second).second)
509  .second;
510  output_.pMtdSimTracksters->emplace_back(sc, LC_indices, timeAtEntrance, posAtEntrance);
511  SC_index++;
512  }
513 
514 #ifdef PRINT_DEBUG
515  IfLogDebug(DEBUG, messageCategory_) << "SIMLAYERCLUSTERS LIST: \n";
516  for (auto &sc : *output_.pMtdSimLayerClusters) {
517  IfLogDebug(DEBUG, messageCategory_) << std::fixed << std::setprecision(3) << "SimLayerCluster with:"
518  << "\n CP charge " << sc.charge() << "\n CP pdgId " << sc.pdgId()
519  << "\n CP energy " << sc.energy() << " GeV\n CP eta " << sc.eta()
520  << "\n CP phi " << sc.phi()
521  << "\n number of cells = " << sc.hits_and_fractions().size() << std::endl;
522  for (unsigned int i = 0; i < sc.hits_and_fractions().size(); ++i) {
523  DetId id(sc.detIds_and_rows()[i].first);
525  << std::fixed << std::setprecision(3) << " hit " << sc.detIds_and_rows()[i].first << " on layer "
526  << geomTools_.layer(id) << " at time " << sc.hits_and_times()[i].second << " ns" << std::endl;
527  }
528  IfLogDebug(DEBUG, messageCategory_) << std::fixed << std::setprecision(3) << " Cluster time " << sc.simLCTime()
529  << " ns \n Cluster pos" << sc.simLCPos() << " cm\n"
530  << std::fixed << std::setprecision(6) << " Cluster energy "
531  << convertUnitsTo(0.001_MeV, sc.simLCEnergy()) << " MeV" << std::endl;
532  IfLogDebug(DEBUG, messageCategory_) << "--------------\n";
533  }
534  IfLogDebug(DEBUG, messageCategory_) << std::endl;
535 
536  IfLogDebug(DEBUG, messageCategory_) << "SIMTRACKSTERS LIST: \n";
537  for (auto &sc : *output_.pMtdSimTracksters) {
538  IfLogDebug(DEBUG, messageCategory_) << std::fixed << std::setprecision(3) << "SimTrackster with:"
539  << "\n CP charge " << sc.charge() << "\n CP pdgId " << sc.pdgId()
540  << "\n CP energy " << sc.energy() << " GeV\n CP eta " << sc.eta()
541  << "\n CP phi " << sc.phi()
542  << "\n number of layer clusters = " << sc.numberOfClusters()
543  << "\n time of first simhit " << sc.time() << " ns\n position of first simhit"
544  << sc.position() << "cm" << std::endl;
545  IfLogDebug(DEBUG, messageCategory_) << " LCs indices: ";
546  for (const auto &lc : sc.clusters())
547  IfLogDebug(DEBUG, messageCategory_) << lc << ", ";
548  IfLogDebug(DEBUG, messageCategory_) << "\n--------------\n";
549  }
550  IfLogDebug(DEBUG, messageCategory_) << std::endl;
551 #endif
552 
553  event.put(std::move(output_.pMtdSimLayerClusters), "MergedMtdTruthLC");
554  event.put(std::move(output_.pMtdSimTracksters), "MergedMtdTruthST");
555 
556  // now fill the calo particles
557  for (unsigned i = 0; i < output_.pCaloParticles->size(); ++i) {
558  auto &cp = (*output_.pCaloParticles)[i];
559  for (unsigned j = m_caloParticles.sc_start_[i]; j < m_caloParticles.sc_stop_[i]; ++j) {
560  edm::Ref<MtdSimClusterCollection> ref(scHandle, j);
561  cp.addSimCluster(ref);
562  }
563  }
564  event.put(std::move(output_.pCaloParticles), "MergedMtdTruth");
565 
566  calo_particles().swap(m_caloParticles);
567 
568  std::unordered_map<uint64_t, float>().swap(m_detIdToTotalSimEnergy);
569  std::unordered_multimap<Barcode_t, Index_t>().swap(m_simHitBarcodeToIndex);
570 }
std::unique_ptr< MtdCaloParticleCollection > pCaloParticles
const std::string messageCategory_
#define DEBUG
std::unique_ptr< MtdSimTracksterCollection > pMtdSimTracksters
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:112
constexpr NumType convertUnitsTo(double desiredUnits, NumType val)
Definition: GeantUnits.h:73
U second(std::pair< T, U > const &p)
#define IfLogDebug(cond, cat)
std::unique_ptr< MtdSimLayerClusterCollection > pMtdSimLayerClusters
unsigned int layer(const DetId &) const
Definition: MTDGeomUtil.cc:89
std::unordered_multimap< Barcode_t, Index_t > m_simHitBarcodeToIndex
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
OutputCollections output_
std::pair< LocalPoint, GlobalPoint > position(const DetId &id, int row=0, int column=0) const
Definition: MTDGeomUtil.cc:27
std::unique_ptr< MtdSimClusterCollection > pSimClusters
calo_particles m_caloParticles
Log< level::Info, false > LogInfo
Definition: DetId.h:17
bool isETL(const DetId &) const
Definition: MTDGeomUtil.cc:14
double b
Definition: hdecay.h:120
std::unordered_map< uint64_t, float > m_detIdToTotalSimEnergy
double a
Definition: hdecay.h:121
static int position[264][3]
Definition: ReadPGInfo.cc:289
int module(const DetId &) const
Definition: MTDGeomUtil.cc:98
Log< level::Warning, false > LogWarning
mtd::MTDGeomUtil geomTools_
def move(src, dest)
Definition: eostools.py:511

◆ initializeEvent()

void MtdTruthAccumulator::initializeEvent ( const edm::Event event,
const edm::EventSetup setup 
)
overrideprivatevirtual

Implements DigiAccumulatorMixMod.

Definition at line 291 of file MtdTruthAccumulator.cc.

References geom, geomToken_, geomTools_, m_detIdToTotalSimEnergy, mtdtopoToken_, output_, MtdTruthAccumulator::OutputCollections::pCaloParticles, MtdTruthAccumulator::OutputCollections::pMtdSimLayerClusters, MtdTruthAccumulator::OutputCollections::pMtdSimTracksters, MtdTruthAccumulator::OutputCollections::pSimClusters, mtd::MTDGeomUtil::setGeometry(), mtd::MTDGeomUtil::setTopology(), singleTopDQM_cfi::setup, and topology.

291  {
292  output_.pSimClusters = std::make_unique<MtdSimClusterCollection>();
293  output_.pCaloParticles = std::make_unique<MtdCaloParticleCollection>();
294 
295  output_.pMtdSimLayerClusters = std::make_unique<MtdSimLayerClusterCollection>();
296  output_.pMtdSimTracksters = std::make_unique<MtdSimTracksterCollection>();
297 
298  m_detIdToTotalSimEnergy.clear();
299 
300  auto geometryHandle = setup.getTransientHandle(geomToken_);
301  geom = geometryHandle.product();
302 
303  auto topologyHandle = setup.getTransientHandle(mtdtopoToken_);
304  topology = topologyHandle.product();
305 
308 }
const edm::ESGetToken< MTDTopology, MTDTopologyRcd > mtdtopoToken_
std::unique_ptr< MtdCaloParticleCollection > pCaloParticles
const edm::ESGetToken< MTDGeometry, MTDDigiGeometryRecord > geomToken_
const MTDGeometry * geom
const MTDTopology * topology
std::unique_ptr< MtdSimTracksterCollection > pMtdSimTracksters
void setTopology(MTDTopology const *topo)
Definition: MTDGeomUtil.cc:12
std::unique_ptr< MtdSimLayerClusterCollection > pMtdSimLayerClusters
OutputCollections output_
std::unique_ptr< MtdSimClusterCollection > pSimClusters
void setGeometry(MTDGeometry const *geom)
Definition: MTDGeomUtil.cc:10
std::unordered_map< uint64_t, float > m_detIdToTotalSimEnergy
mtd::MTDGeomUtil geomTools_

Member Data Documentation

◆ bunchSpacing_

const unsigned int MtdTruthAccumulator::bunchSpacing_
private

Definition at line 109 of file MtdTruthAccumulator.cc.

Referenced by accumulateEvent().

◆ collectionTags_

std::vector<edm::InputTag> MtdTruthAccumulator::collectionTags_
private

Definition at line 116 of file MtdTruthAccumulator.cc.

Referenced by fillSimHits(), and MtdTruthAccumulator().

◆ genParticleLabel_

edm::InputTag MtdTruthAccumulator::genParticleLabel_
private

Definition at line 117 of file MtdTruthAccumulator.cc.

Referenced by accumulateEvent(), and MtdTruthAccumulator().

◆ geom

const MTDGeometry* MtdTruthAccumulator::geom = nullptr
private

Definition at line 155 of file MtdTruthAccumulator.cc.

Referenced by initializeEvent().

◆ geomToken_

const edm::ESGetToken<MTDGeometry, MTDDigiGeometryRecord> MtdTruthAccumulator::geomToken_
private

Definition at line 120 of file MtdTruthAccumulator.cc.

Referenced by initializeEvent().

◆ geomTools_

mtd::MTDGeomUtil MtdTruthAccumulator::geomTools_
private

Definition at line 124 of file MtdTruthAccumulator.cc.

Referenced by fillSimHits(), finalizeEvent(), and initializeEvent().

◆ hepMCproductLabel_

edm::InputTag MtdTruthAccumulator::hepMCproductLabel_
private

Needed to add HepMC::GenVertex to SimVertex.

Definition at line 119 of file MtdTruthAccumulator.cc.

Referenced by accumulate(), and MtdTruthAccumulator().

◆ hSimTracks

edm::Handle<std::vector<SimTrack> > MtdTruthAccumulator::hSimTracks
private

Definition at line 113 of file MtdTruthAccumulator.cc.

Referenced by accumulateEvent().

◆ hSimVertices

edm::Handle<std::vector<SimVertex> > MtdTruthAccumulator::hSimVertices
private

Definition at line 114 of file MtdTruthAccumulator.cc.

Referenced by accumulateEvent().

◆ isEtl_

bool MtdTruthAccumulator::isEtl_
private

Definition at line 129 of file MtdTruthAccumulator.cc.

Referenced by MtdTruthAccumulator().

◆ m_caloParticles

calo_particles MtdTruthAccumulator::m_caloParticles
private

Definition at line 158 of file MtdTruthAccumulator.cc.

Referenced by accumulateEvent(), and finalizeEvent().

◆ m_detIdToTotalSimEnergy

std::unordered_map<uint64_t, float> MtdTruthAccumulator::m_detIdToTotalSimEnergy
private

Definition at line 93 of file MtdTruthAccumulator.cc.

Referenced by fillSimHits(), finalizeEvent(), and initializeEvent().

◆ m_simHitBarcodeToIndex

std::unordered_multimap<Barcode_t, Index_t> MtdTruthAccumulator::m_simHitBarcodeToIndex
private

Definition at line 94 of file MtdTruthAccumulator.cc.

Referenced by accumulateEvent(), and finalizeEvent().

◆ maximumPreviousBunchCrossing_

const unsigned int MtdTruthAccumulator::maximumPreviousBunchCrossing_
private

The maximum bunch crossing BEFORE the signal crossing to create TrackinParticles for. Use positive values. If set to zero no previous bunches are added and only in-time, signal and after bunches (defined by maximumSubsequentBunchCrossing_) are used.

Definition at line 101 of file MtdTruthAccumulator.cc.

Referenced by accumulate().

◆ maximumSubsequentBunchCrossing_

const unsigned int MtdTruthAccumulator::maximumSubsequentBunchCrossing_
private

The maximum bunch crossing AFTER the signal crossing to create TrackinParticles for. E.g. if set to zero only uses the signal and in time pileup (and previous bunches defined by the maximumPreviousBunchCrossing_ parameter).

Definition at line 107 of file MtdTruthAccumulator.cc.

Referenced by accumulate().

◆ maxPseudoRapidity_

const double MtdTruthAccumulator::maxPseudoRapidity_
private

Definition at line 126 of file MtdTruthAccumulator.cc.

Referenced by accumulateEvent().

◆ messageCategory_

const std::string MtdTruthAccumulator::messageCategory_
private

Definition at line 91 of file MtdTruthAccumulator.cc.

Referenced by accumulate(), accumulateEvent(), fillSimHits(), and finalizeEvent().

◆ minEnergy_

const double MtdTruthAccumulator::minEnergy_
private

Definition at line 126 of file MtdTruthAccumulator.cc.

Referenced by accumulateEvent().

◆ mtdtopoToken_

const edm::ESGetToken<MTDTopology, MTDTopologyRcd> MtdTruthAccumulator::mtdtopoToken_
private

Definition at line 121 of file MtdTruthAccumulator.cc.

Referenced by initializeEvent().

◆ output_

OutputCollections MtdTruthAccumulator::output_
private

Definition at line 157 of file MtdTruthAccumulator.cc.

Referenced by accumulateEvent(), finalizeEvent(), and initializeEvent().

◆ premixStage1_

const bool MtdTruthAccumulator::premixStage1_
private

Definition at line 127 of file MtdTruthAccumulator.cc.

Referenced by finalizeEvent(), and MtdTruthAccumulator().

◆ simTrackLabel_

const edm::InputTag MtdTruthAccumulator::simTrackLabel_
private

Definition at line 111 of file MtdTruthAccumulator.cc.

Referenced by accumulateEvent(), and MtdTruthAccumulator().

◆ simVertexLabel_

const edm::InputTag MtdTruthAccumulator::simVertexLabel_
private

Definition at line 112 of file MtdTruthAccumulator.cc.

Referenced by accumulateEvent(), and MtdTruthAccumulator().

◆ topology

const MTDTopology* MtdTruthAccumulator::topology = nullptr
private

Definition at line 156 of file MtdTruthAccumulator.cc.

Referenced by initializeEvent().