File indexing completed on 2024-04-06 12:30:31
0001 #define DEBUG false
0002
0003 #if DEBUG
0004 #pragma GCC diagnostic pop
0005 #endif
0006
0007 #include <iterator>
0008 #include <memory>
0009
0010 #include <numeric> // for std::accumulate
0011 #include <unordered_map>
0012
0013 #include "FWCore/Framework/interface/ConsumesCollector.h"
0014 #include "FWCore/Framework/interface/ESWatcher.h"
0015 #include "FWCore/Framework/interface/Event.h"
0016 #include "FWCore/Framework/interface/EventSetup.h"
0017 #include "FWCore/Framework/interface/ProducesCollector.h"
0018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0019 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0020 #include "FWCore/Utilities/interface/InputTag.h"
0021
0022 #include "DataFormats/ForwardDetId/interface/HGCalDetId.h"
0023 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
0024 #include "DataFormats/HcalDetId/interface/HcalTestNumbering.h"
0025 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
0026 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
0027 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
0028
0029 #include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h"
0030 #include "SimDataFormats/CaloAnalysis/interface/CaloParticleFwd.h"
0031 #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h"
0032 #include "SimDataFormats/CaloAnalysis/interface/SimClusterFwd.h"
0033 #include "SimDataFormats/CaloHit/interface/PCaloHit.h"
0034 #include "SimDataFormats/CaloTest/interface/HGCalTestNumbering.h"
0035 #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
0036 #include "SimDataFormats/Vertex/interface/SimVertex.h"
0037
0038 #include "SimGeneral/MixingModule/interface/DecayGraph.h"
0039 #include "SimGeneral/MixingModule/interface/DigiAccumulatorMixMod.h"
0040 #include "SimGeneral/MixingModule/interface/DigiAccumulatorMixModFactory.h"
0041 #include "SimGeneral/MixingModule/interface/PileUpEventPrincipal.h"
0042 #include "SimGeneral/TrackingAnalysis/interface/EncodedTruthId.h"
0043
0044 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
0045 #include "Geometry/HGCalGeometry/interface/HGCalGeometry.h"
0046 #include "Geometry/HcalCommonData/interface/HcalHitRelabeller.h"
0047 #include "Geometry/HcalTowerAlgo/interface/HcalGeometry.h"
0048 #include "Geometry/Records/interface/CaloGeometryRecord.h"
0049
0050 namespace {
0051 using Index_t = unsigned;
0052 using Barcode_t = int;
0053 const std::string messageCategoryGraph_("CaloTruthAccumulatorGraphProducer");
0054 }
0055
0056 class CaloTruthAccumulator : public DigiAccumulatorMixMod {
0057 public:
0058 explicit CaloTruthAccumulator(const edm::ParameterSet &config, edm::ProducesCollector, edm::ConsumesCollector &iC);
0059
0060 private:
0061 void initializeEvent(const edm::Event &event, const edm::EventSetup &setup) override;
0062 void accumulate(const edm::Event &event, const edm::EventSetup &setup) override;
0063 void accumulate(const PileUpEventPrincipal &event, const edm::EventSetup &setup, edm::StreamID const &) override;
0064 void finalizeEvent(edm::Event &event, const edm::EventSetup &setup) override;
0065
0066
0067 template <class T>
0068 void accumulateEvent(const T &event,
0069 const edm::EventSetup &setup,
0070 const edm::Handle<edm::HepMCProduct> &hepMCproduct);
0071
0072
0073
0074 template <class T>
0075 void fillSimHits(std::vector<std::pair<DetId, const PCaloHit *>> &returnValue,
0076 std::unordered_map<int, std::map<int, float>> &simTrackDetIdEnergyMap,
0077 const T &event,
0078 const edm::EventSetup &setup);
0079
0080 const std::string messageCategory_;
0081
0082 std::unordered_map<Index_t, float> m_detIdToTotalSimEnergy;
0083 std::unordered_multimap<Barcode_t, Index_t> m_simHitBarcodeToIndex;
0084
0085
0086
0087
0088
0089
0090 const unsigned int maximumPreviousBunchCrossing_;
0091
0092
0093
0094
0095
0096 const unsigned int maximumSubsequentBunchCrossing_;
0097
0098 const edm::InputTag simTrackLabel_;
0099 const edm::InputTag simVertexLabel_;
0100 edm::Handle<std::vector<SimTrack>> hSimTracks;
0101 edm::Handle<std::vector<SimVertex>> hSimVertices;
0102
0103 std::vector<edm::InputTag> collectionTags_;
0104 edm::InputTag genParticleLabel_;
0105
0106 edm::InputTag hepMCproductLabel_;
0107 const edm::ESGetToken<CaloGeometry, CaloGeometryRecord> geomToken_;
0108 edm::ESWatcher<CaloGeometryRecord> geomWatcher_;
0109
0110 const double minEnergy_, maxPseudoRapidity_;
0111 const bool premixStage1_;
0112
0113 public:
0114 struct OutputCollections {
0115 std::unique_ptr<SimClusterCollection> pSimClusters;
0116 std::unique_ptr<CaloParticleCollection> pCaloParticles;
0117 };
0118
0119 struct calo_particles {
0120 std::vector<uint32_t> sc_start_;
0121 std::vector<uint32_t> sc_stop_;
0122
0123 void swap(calo_particles &oth) {
0124 sc_start_.swap(oth.sc_start_);
0125 sc_stop_.swap(oth.sc_stop_);
0126 }
0127
0128 void clear() {
0129 sc_start_.clear();
0130 sc_stop_.clear();
0131 }
0132 };
0133
0134 private:
0135 const HGCalTopology *hgtopo_[3] = {nullptr, nullptr, nullptr};
0136 const HGCalDDDConstants *hgddd_[3] = {nullptr, nullptr, nullptr};
0137 const HcalDDDRecConstants *hcddd_ = nullptr;
0138 OutputCollections output_;
0139 calo_particles m_caloParticles;
0140
0141 int geometryType_;
0142 bool doHGCAL;
0143 };
0144
0145
0146
0147 namespace {
0148 class CaloParticle_dfs_visitor : public boost::default_dfs_visitor {
0149 public:
0150 CaloParticle_dfs_visitor(CaloTruthAccumulator::OutputCollections &output,
0151 CaloTruthAccumulator::calo_particles &caloParticles,
0152 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex,
0153 std::unordered_map<int, std::map<int, float>> &simTrackDetIdEnergyMap,
0154 Selector selector)
0155 : output_(output),
0156 caloParticles_(caloParticles),
0157 simHitBarcodeToIndex_(simHitBarcodeToIndex),
0158 simTrackDetIdEnergyMap_(simTrackDetIdEnergyMap),
0159 selector_(selector) {}
0160 template <typename Vertex, typename Graph>
0161 void discover_vertex(Vertex u, const Graph &g) {
0162
0163
0164
0165 print_vertex(u, g);
0166 auto const vertex_property = get(vertex_name, g, u);
0167 if (!vertex_property.simTrack)
0168 return;
0169 auto trackIdx = vertex_property.simTrack->trackId();
0170 IfLogDebug(DEBUG, messageCategoryGraph_)
0171 << " Found " << simHitBarcodeToIndex_.count(trackIdx) << " associated simHits" << std::endl;
0172 if (simHitBarcodeToIndex_.count(trackIdx)) {
0173 output_.pSimClusters->emplace_back(*vertex_property.simTrack);
0174 auto &simcluster = output_.pSimClusters->back();
0175 std::unordered_map<uint32_t, float> acc_energy;
0176 for (auto const &hit_and_energy : simTrackDetIdEnergyMap_[trackIdx]) {
0177 acc_energy[hit_and_energy.first] += hit_and_energy.second;
0178 }
0179 for (auto const &hit_and_energy : acc_energy) {
0180 simcluster.addRecHitAndFraction(hit_and_energy.first, hit_and_energy.second);
0181 }
0182 }
0183 }
0184 template <typename Edge, typename Graph>
0185 void examine_edge(Edge e, const Graph &g) {
0186 auto src = source(e, g);
0187 auto vertex_property = get(vertex_name, g, src);
0188 if (src == 0 or (vertex_property.simTrack == nullptr)) {
0189 auto edge_property = get(edge_weight, g, e);
0190 IfLogDebug(DEBUG, messageCategoryGraph_) << "Considering CaloParticle: " << edge_property.simTrack->trackId();
0191 if (selector_(edge_property)) {
0192 IfLogDebug(DEBUG, messageCategoryGraph_) << "Adding CaloParticle: " << edge_property.simTrack->trackId();
0193 output_.pCaloParticles->emplace_back(*(edge_property.simTrack));
0194 caloParticles_.sc_start_.push_back(output_.pSimClusters->size());
0195 }
0196 }
0197 }
0198
0199 template <typename Edge, typename Graph>
0200 void finish_edge(Edge e, const Graph &g) {
0201 auto src = source(e, g);
0202 auto vertex_property = get(vertex_name, g, src);
0203 if (src == 0 or (vertex_property.simTrack == nullptr)) {
0204 auto edge_property = get(edge_weight, g, e);
0205 if (selector_(edge_property)) {
0206 caloParticles_.sc_stop_.push_back(output_.pSimClusters->size());
0207 }
0208 }
0209 }
0210
0211 private:
0212 CaloTruthAccumulator::OutputCollections &output_;
0213 CaloTruthAccumulator::calo_particles &caloParticles_;
0214 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex_;
0215 std::unordered_map<int, std::map<int, float>> &simTrackDetIdEnergyMap_;
0216 Selector selector_;
0217 };
0218 }
0219
0220 CaloTruthAccumulator::CaloTruthAccumulator(const edm::ParameterSet &config,
0221 edm::ProducesCollector producesCollector,
0222 edm::ConsumesCollector &iC)
0223 : messageCategory_("CaloTruthAccumulator"),
0224 maximumPreviousBunchCrossing_(config.getParameter<unsigned int>("maximumPreviousBunchCrossing")),
0225 maximumSubsequentBunchCrossing_(config.getParameter<unsigned int>("maximumSubsequentBunchCrossing")),
0226 simTrackLabel_(config.getParameter<edm::InputTag>("simTrackCollection")),
0227 simVertexLabel_(config.getParameter<edm::InputTag>("simVertexCollection")),
0228 collectionTags_(),
0229 genParticleLabel_(config.getParameter<edm::InputTag>("genParticleCollection")),
0230 hepMCproductLabel_(config.getParameter<edm::InputTag>("HepMCProductLabel")),
0231 geomToken_(iC.esConsumes()),
0232 minEnergy_(config.getParameter<double>("MinEnergy")),
0233 maxPseudoRapidity_(config.getParameter<double>("MaxPseudoRapidity")),
0234 premixStage1_(config.getParameter<bool>("premixStage1")),
0235 geometryType_(-1),
0236 doHGCAL(config.getParameter<bool>("doHGCAL")) {
0237 producesCollector.produces<SimClusterCollection>("MergedCaloTruth");
0238 producesCollector.produces<CaloParticleCollection>("MergedCaloTruth");
0239 if (premixStage1_) {
0240 producesCollector.produces<std::vector<std::pair<unsigned int, float>>>("MergedCaloTruth");
0241 }
0242
0243 iC.consumes<std::vector<SimTrack>>(simTrackLabel_);
0244 iC.consumes<std::vector<SimVertex>>(simVertexLabel_);
0245 iC.consumes<std::vector<reco::GenParticle>>(genParticleLabel_);
0246 iC.consumes<std::vector<int>>(genParticleLabel_);
0247 iC.consumes<std::vector<int>>(hepMCproductLabel_);
0248
0249
0250 const edm::ParameterSet &simHitCollectionConfig = config.getParameterSet("simHitCollections");
0251 std::vector<std::string> parameterNames = simHitCollectionConfig.getParameterNames();
0252
0253 for (auto const ¶meterName : parameterNames) {
0254 std::vector<edm::InputTag> tags = simHitCollectionConfig.getParameter<std::vector<edm::InputTag>>(parameterName);
0255 collectionTags_.insert(collectionTags_.end(), tags.begin(), tags.end());
0256 }
0257
0258 for (auto const &collectionTag : collectionTags_) {
0259 iC.consumes<std::vector<PCaloHit>>(collectionTag);
0260 }
0261 }
0262
0263 void CaloTruthAccumulator::initializeEvent(edm::Event const &event, edm::EventSetup const &setup) {
0264 output_.pSimClusters = std::make_unique<SimClusterCollection>();
0265 output_.pCaloParticles = std::make_unique<CaloParticleCollection>();
0266
0267 m_detIdToTotalSimEnergy.clear();
0268
0269 if (geomWatcher_.check(setup)) {
0270 auto const &geom = setup.getData(geomToken_);
0271 const HGCalGeometry *eegeom = nullptr, *fhgeom = nullptr, *bhgeomnew = nullptr;
0272 const HcalGeometry *bhgeom = nullptr;
0273 bhgeom = static_cast<const HcalGeometry *>(geom.getSubdetectorGeometry(DetId::Hcal, HcalEndcap));
0274
0275 if (doHGCAL) {
0276 eegeom = static_cast<const HGCalGeometry *>(
0277 geom.getSubdetectorGeometry(DetId::HGCalEE, ForwardSubdetector::ForwardEmpty));
0278
0279 if (eegeom) {
0280 geometryType_ = 1;
0281 fhgeom = static_cast<const HGCalGeometry *>(
0282 geom.getSubdetectorGeometry(DetId::HGCalHSi, ForwardSubdetector::ForwardEmpty));
0283 bhgeomnew = static_cast<const HGCalGeometry *>(
0284 geom.getSubdetectorGeometry(DetId::HGCalHSc, ForwardSubdetector::ForwardEmpty));
0285 } else {
0286 geometryType_ = 0;
0287 eegeom = static_cast<const HGCalGeometry *>(geom.getSubdetectorGeometry(DetId::Forward, HGCEE));
0288 fhgeom = static_cast<const HGCalGeometry *>(geom.getSubdetectorGeometry(DetId::Forward, HGCHEF));
0289 bhgeom = static_cast<const HcalGeometry *>(geom.getSubdetectorGeometry(DetId::Hcal, HcalEndcap));
0290 }
0291 hgtopo_[0] = &(eegeom->topology());
0292 hgtopo_[1] = &(fhgeom->topology());
0293 if (bhgeomnew)
0294 hgtopo_[2] = &(bhgeomnew->topology());
0295
0296 for (unsigned i = 0; i < 3; ++i) {
0297 if (hgtopo_[i])
0298 hgddd_[i] = &(hgtopo_[i]->dddConstants());
0299 }
0300 }
0301
0302 if (bhgeom) {
0303 hcddd_ = bhgeom->topology().dddConstants();
0304 }
0305 }
0306 }
0307
0308
0309
0310
0311
0312
0313
0314
0315 void CaloTruthAccumulator::accumulate(edm::Event const &event, edm::EventSetup const &setup) {
0316 edm::Handle<edm::HepMCProduct> hepmc;
0317 event.getByLabel(hepMCproductLabel_, hepmc);
0318
0319 edm::LogInfo(messageCategory_) << " CaloTruthAccumulator::accumulate (signal)";
0320 accumulateEvent(event, setup, hepmc);
0321 }
0322
0323 void CaloTruthAccumulator::accumulate(PileUpEventPrincipal const &event,
0324 edm::EventSetup const &setup,
0325 edm::StreamID const &) {
0326 if (event.bunchCrossing() >= -static_cast<int>(maximumPreviousBunchCrossing_) &&
0327 event.bunchCrossing() <= static_cast<int>(maximumSubsequentBunchCrossing_)) {
0328
0329 edm::Handle<edm::HepMCProduct> hepmc;
0330 edm::LogInfo(messageCategory_) << " CaloTruthAccumulator::accumulate (pileup) bunchCrossing="
0331 << event.bunchCrossing();
0332 accumulateEvent(event, setup, hepmc);
0333 } else {
0334 edm::LogInfo(messageCategory_) << "Skipping pileup event for bunch crossing " << event.bunchCrossing();
0335 }
0336 }
0337
0338 void CaloTruthAccumulator::finalizeEvent(edm::Event &event, edm::EventSetup const &setup) {
0339 edm::LogInfo(messageCategory_) << "Adding " << output_.pSimClusters->size() << " SimParticles and "
0340 << output_.pCaloParticles->size() << " CaloParticles to the event.";
0341
0342
0343
0344
0345
0346
0347 if (premixStage1_) {
0348 auto totalEnergies = std::make_unique<std::vector<std::pair<unsigned int, float>>>();
0349 totalEnergies->reserve(m_detIdToTotalSimEnergy.size());
0350 std::copy(m_detIdToTotalSimEnergy.begin(), m_detIdToTotalSimEnergy.end(), std::back_inserter(*totalEnergies));
0351 std::sort(totalEnergies->begin(), totalEnergies->end());
0352 event.put(std::move(totalEnergies), "MergedCaloTruth");
0353 } else {
0354 for (auto &sc : *(output_.pSimClusters)) {
0355 auto hitsAndEnergies = sc.hits_and_fractions();
0356 sc.clearHitsAndFractions();
0357 sc.clearHitsEnergy();
0358 for (auto &hAndE : hitsAndEnergies) {
0359 const float totalenergy = m_detIdToTotalSimEnergy[hAndE.first];
0360 float fraction = 0.;
0361 if (totalenergy > 0)
0362 fraction = hAndE.second / totalenergy;
0363 else
0364 edm::LogWarning(messageCategory_)
0365 << "TotalSimEnergy for hit " << hAndE.first << " is 0! The fraction for this hit cannot be computed.";
0366 sc.addRecHitAndFraction(hAndE.first, fraction);
0367 sc.addHitEnergy(hAndE.second);
0368 }
0369 }
0370 }
0371
0372
0373 auto scHandle = event.put(std::move(output_.pSimClusters), "MergedCaloTruth");
0374
0375
0376 for (unsigned i = 0; i < output_.pCaloParticles->size(); ++i) {
0377 auto &cp = (*output_.pCaloParticles)[i];
0378 for (unsigned j = m_caloParticles.sc_start_[i]; j < m_caloParticles.sc_stop_[i]; ++j) {
0379 edm::Ref<SimClusterCollection> ref(scHandle, j);
0380 cp.addSimCluster(ref);
0381 }
0382 }
0383
0384 event.put(std::move(output_.pCaloParticles), "MergedCaloTruth");
0385
0386 calo_particles().swap(m_caloParticles);
0387
0388 std::unordered_map<Index_t, float>().swap(m_detIdToTotalSimEnergy);
0389 std::unordered_multimap<Barcode_t, Index_t>().swap(m_simHitBarcodeToIndex);
0390 }
0391
0392 template <class T>
0393 void CaloTruthAccumulator::accumulateEvent(const T &event,
0394 const edm::EventSetup &setup,
0395 const edm::Handle<edm::HepMCProduct> &hepMCproduct) {
0396 edm::Handle<std::vector<reco::GenParticle>> hGenParticles;
0397 edm::Handle<std::vector<int>> hGenParticleIndices;
0398
0399 event.getByLabel(simTrackLabel_, hSimTracks);
0400 event.getByLabel(simVertexLabel_, hSimVertices);
0401
0402 event.getByLabel(genParticleLabel_, hGenParticles);
0403 event.getByLabel(genParticleLabel_, hGenParticleIndices);
0404
0405 std::vector<std::pair<DetId, const PCaloHit *>> simHitPointers;
0406 std::unordered_map<int, std::map<int, float>> simTrackDetIdEnergyMap;
0407 fillSimHits(simHitPointers, simTrackDetIdEnergyMap, event, setup);
0408
0409
0410 m_simHitBarcodeToIndex.clear();
0411 for (unsigned int i = 0; i < simHitPointers.size(); ++i) {
0412 m_simHitBarcodeToIndex.emplace(simHitPointers[i].second->geantTrackId(), i);
0413 }
0414
0415 auto const &tracks = *hSimTracks;
0416 auto const &vertices = *hSimVertices;
0417 std::unordered_map<int, int> trackid_to_track_index;
0418 DecayChain decay;
0419 int idx = 0;
0420
0421 IfLogDebug(DEBUG, messageCategory_) << " TRACKS" << std::endl;
0422 for (auto const &t : tracks) {
0423 IfLogDebug(DEBUG, messageCategory_) << " " << idx << "\t" << t.trackId() << "\t" << t << std::endl;
0424 trackid_to_track_index[t.trackId()] = idx;
0425 idx++;
0426 }
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454 idx = 0;
0455 std::vector<int> used_sim_tracks(tracks.size(), 0);
0456 std::vector<int> collapsed_vertices(vertices.size(), 0);
0457 IfLogDebug(DEBUG, messageCategory_) << " VERTICES" << std::endl;
0458 for (auto const &v : vertices) {
0459 IfLogDebug(DEBUG, messageCategory_) << " " << idx++ << "\t" << v << std::endl;
0460 if (v.parentIndex() != -1) {
0461 auto trk_idx = trackid_to_track_index[v.parentIndex()];
0462 auto origin_vtx = tracks[trk_idx].vertIndex();
0463 if (used_sim_tracks[trk_idx]) {
0464
0465
0466
0467 collapsed_vertices[v.vertexId()] = used_sim_tracks[trk_idx];
0468 continue;
0469 }
0470
0471 if (collapsed_vertices[origin_vtx])
0472 origin_vtx = collapsed_vertices[origin_vtx];
0473 add_edge(origin_vtx,
0474 v.vertexId(),
0475 EdgeProperty(&tracks[trk_idx], simTrackDetIdEnergyMap[v.parentIndex()].size(), 0),
0476 decay);
0477 used_sim_tracks[trk_idx] = v.vertexId();
0478 }
0479 }
0480
0481 auto const &vertexMothersProp = get(vertex_name, decay);
0482
0483
0484 int offset = vertices.size();
0485 for (size_t i = 0; i < tracks.size(); ++i) {
0486 if (!used_sim_tracks[i]) {
0487 auto origin_vtx = tracks[i].vertIndex();
0488
0489 if (collapsed_vertices[origin_vtx])
0490 origin_vtx = collapsed_vertices[origin_vtx];
0491 add_edge(
0492 origin_vtx, offset, EdgeProperty(&tracks[i], simTrackDetIdEnergyMap[tracks[i].trackId()].size(), 0), decay);
0493
0494
0495
0496 put(vertexMothersProp, offset, VertexProperty(&tracks[i], 0));
0497 offset++;
0498 }
0499 }
0500 for (auto const &v : vertices) {
0501 if (v.parentIndex() != -1) {
0502
0503 if (collapsed_vertices[v.vertexId()])
0504 continue;
0505 put(vertexMothersProp, v.vertexId(), VertexProperty(&tracks[trackid_to_track_index[v.parentIndex()]], 0));
0506 }
0507 }
0508 SimHitsAccumulator_dfs_visitor vis;
0509 depth_first_search(decay, visitor(vis));
0510 CaloParticle_dfs_visitor caloParticleCreator(
0511 output_,
0512 m_caloParticles,
0513 m_simHitBarcodeToIndex,
0514 simTrackDetIdEnergyMap,
0515 [&](EdgeProperty &edge_property) -> bool {
0516
0517
0518
0519
0520 return (edge_property.cumulative_simHits != 0 and !edge_property.simTrack->noGenpart() and
0521 edge_property.simTrack->momentum().E() > minEnergy_ and
0522 std::abs(edge_property.simTrack->momentum().Eta()) < maxPseudoRapidity_);
0523 });
0524 depth_first_search(decay, visitor(caloParticleCreator));
0525
0526 #if DEBUG
0527 boost::write_graphviz(std::cout,
0528 decay,
0529 make_label_writer(make_transform_value_property_map(&graphviz_vertex, get(vertex_name, decay))),
0530 make_label_writer(make_transform_value_property_map(&graphviz_edge, get(edge_weight, decay))));
0531 #endif
0532 }
0533
0534 template <class T>
0535 void CaloTruthAccumulator::fillSimHits(std::vector<std::pair<DetId, const PCaloHit *>> &returnValue,
0536 std::unordered_map<int, std::map<int, float>> &simTrackDetIdEnergyMap,
0537 const T &event,
0538 const edm::EventSetup &setup) {
0539 for (auto const &collectionTag : collectionTags_) {
0540 edm::Handle<std::vector<PCaloHit>> hSimHits;
0541 const bool isHcal = (collectionTag.instance().find("HcalHits") != std::string::npos);
0542 event.getByLabel(collectionTag, hSimHits);
0543
0544 for (auto const &simHit : *hSimHits) {
0545 DetId id(0);
0546
0547
0548 if (doHGCAL) {
0549 const uint32_t simId = simHit.id();
0550 if (geometryType_ == 1) {
0551
0552 id = simId;
0553 } else if (isHcal) {
0554 HcalDetId hid = HcalHitRelabeller::relabel(simId, hcddd_);
0555 if (hid.subdet() == HcalEndcap)
0556 id = hid;
0557 } else {
0558 int subdet, layer, cell, sec, subsec, zp;
0559 HGCalTestNumbering::unpackHexagonIndex(simId, subdet, zp, layer, sec, subsec, cell);
0560 const HGCalDDDConstants *ddd = hgddd_[subdet - 3];
0561 std::pair<int, int> recoLayerCell = ddd->simToReco(cell, layer, sec, hgtopo_[subdet - 3]->detectorType());
0562 cell = recoLayerCell.first;
0563 layer = recoLayerCell.second;
0564
0565 if (layer == -1 || simHit.geantTrackId() == 0)
0566 continue;
0567 id = HGCalDetId((ForwardSubdetector)subdet, zp, layer, subsec, sec, cell);
0568 }
0569 } else {
0570 id = simHit.id();
0571
0572 if (isHcal) {
0573 HcalDetId hid = HcalHitRelabeller::relabel(simHit.id(), hcddd_);
0574 id = hid;
0575 }
0576 }
0577
0578 if (id == DetId(0)) {
0579 continue;
0580 }
0581 if (simHit.geantTrackId() == 0) {
0582 continue;
0583 }
0584
0585 returnValue.emplace_back(id, &simHit);
0586 simTrackDetIdEnergyMap[simHit.geantTrackId()][id.rawId()] += simHit.energy();
0587 m_detIdToTotalSimEnergy[id.rawId()] += simHit.energy();
0588 }
0589 }
0590 }
0591
0592
0593 DEFINE_DIGI_ACCUMULATOR(CaloTruthAccumulator);