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