5 #pragma GCC diagnostic push
6 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
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>
16 #pragma GCC diagnostic pop
23 #include <unordered_map>
62 using Index_t = unsigned;
63 using Barcode_t =
int;
64 const std::string messageCategoryGraph_(
"CaloTruthAccumulatorGraphProducer");
67 using boost::add_edge;
68 using boost::adjacency_list;
69 using boost::directedS;
71 using boost::edge_weight;
72 using boost::edge_weight_t;
74 using boost::property;
77 using boost::vertex_name;
78 using boost::vertex_name_t;
124 using DecayChain = adjacency_list<listS, vecS, directedS, VertexMotherParticleProperty, EdgeParticleClustersProperty>;
146 std::unordered_map<
int, std::map<int, float>> &simTrackDetIdEnergyMap,
218 template <
typename Edge,
typename Graph,
typename Visitor>
219 void accumulateSimHits_edge(Edge &
e,
const Graph &
g, Visitor *
v) {
220 auto const edge_property =
get(edge_weight,
g,
e);
221 v->total_simHits += edge_property.simHits;
223 <<
" Examining edges " <<
e <<
" --> particle " << edge_property.simTrack->type() <<
"("
224 << edge_property.simTrack->trackId() <<
")"
225 <<
" with SimClusters: " << edge_property.simHits <<
" Accumulated SimClusters: " <<
v->total_simHits
228 template <
typename Vertex,
typename Graph>
230 auto const vertex_property =
get(vertex_name,
g, u);
233 if (vertex_property.simTrack)
234 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
" [" << vertex_property.simTrack->type() <<
"]"
235 <<
"(" << vertex_property.simTrack->trackId() <<
")";
242 std::ostringstream oss;
243 oss <<
"{id: " << (
v.simTrack ?
v.simTrack->trackId() : 0) <<
",\\ntype: " << (
v.simTrack ?
v.simTrack->type() : 0)
244 <<
",\\nchits: " <<
v.cumulative_simHits <<
"}";
249 std::ostringstream oss;
250 oss <<
"[" << (
e.simTrack ?
e.simTrack->trackId() : 0) <<
"," << (
e.simTrack ?
e.simTrack->type() : 0) <<
","
251 <<
e.simHits <<
"," <<
e.cumulative_simHits <<
"]";
256 class SimHitsAccumulator_dfs_visitor :
public boost::default_dfs_visitor {
258 int total_simHits = 0;
259 template <
typename Edge,
typename Graph>
260 void examine_edge(Edge
e,
const Graph &
g) {
261 accumulateSimHits_edge(
e,
g,
this);
263 template <
typename Edge,
typename Graph>
264 void finish_edge(Edge
e,
const Graph &
g) {
265 auto const edge_property =
get(edge_weight,
g,
e);
268 auto cumulative = edge_property.simHits +
get(vertex_name,
g, trg).cumulative_simHits +
269 (
get(vertex_name,
g,
src).simTrack ?
get(vertex_name,
g,
src).cumulative_simHits
272 auto const src_vertex_property =
get(vertex_name,
g,
src);
274 put(
get(edge_weight, const_cast<Graph &>(
g)),
278 <<
" Finished edge: " <<
e <<
" Track id: " <<
get(edge_weight,
g,
e).simTrack->trackId()
279 <<
" has accumulated " <<
cumulative <<
" hits" << std::endl;
281 <<
"\t" <<
get(vertex_name,
g,
src).cumulative_simHits << std::endl;
282 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
" TrgVtx: " << trg <<
"\t" <<
get(vertex_name,
g, trg).simTrack
283 <<
"\t" <<
get(vertex_name,
g, trg).cumulative_simHits << std::endl;
289 class CaloParticle_dfs_visitor :
public boost::default_dfs_visitor {
293 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex,
294 std::unordered_map<
int, std::map<int, float>> &simTrackDetIdEnergyMap,
298 simHitBarcodeToIndex_(simHitBarcodeToIndex),
299 simTrackDetIdEnergyMap_(simTrackDetIdEnergyMap),
300 selector_(selector) {}
301 template <
typename Vertex,
typename Graph>
307 auto const vertex_property =
get(vertex_name,
g, u);
308 if (!vertex_property.simTrack)
310 auto trackIdx = vertex_property.simTrack->trackId();
312 <<
" Found " << simHitBarcodeToIndex_.count(trackIdx) <<
" associated simHits" << std::endl;
313 if (simHitBarcodeToIndex_.count(trackIdx)) {
314 output_.pSimClusters->emplace_back(*vertex_property.simTrack);
315 auto &simcluster = output_.pSimClusters->back();
316 std::unordered_map<uint32_t, float> acc_energy;
317 for (
auto const &hit_and_energy : simTrackDetIdEnergyMap_[trackIdx]) {
318 acc_energy[hit_and_energy.first] += hit_and_energy.second;
320 for (
auto const &hit_and_energy : acc_energy) {
321 simcluster.addRecHitAndFraction(hit_and_energy.first, hit_and_energy.second);
325 template <
typename Edge,
typename Graph>
326 void examine_edge(Edge
e,
const Graph &
g) {
328 auto vertex_property =
get(vertex_name,
g,
src);
329 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
330 auto edge_property =
get(edge_weight,
g,
e);
331 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
"Considering CaloParticle: " << edge_property.simTrack->trackId();
332 if (selector_(edge_property)) {
333 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
"Adding CaloParticle: " << edge_property.simTrack->trackId();
334 output_.pCaloParticles->emplace_back(*(edge_property.simTrack));
335 caloParticles_.sc_start_.push_back(output_.pSimClusters->size());
340 template <
typename Edge,
typename Graph>
341 void finish_edge(Edge
e,
const Graph &
g) {
343 auto vertex_property =
get(vertex_name,
g,
src);
344 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
345 auto edge_property =
get(edge_weight,
g,
e);
346 if (selector_(edge_property)) {
347 caloParticles_.sc_stop_.push_back(output_.pSimClusters->size());
355 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex_;
356 std::unordered_map<int, std::map<int, float>> &simTrackDetIdEnergyMap_;
364 : messageCategory_(
"CaloTruthAccumulator"),
365 maximumPreviousBunchCrossing_(
config.getParameter<unsigned
int>(
"maximumPreviousBunchCrossing")),
366 maximumSubsequentBunchCrossing_(
config.getParameter<unsigned
int>(
"maximumSubsequentBunchCrossing")),
373 minEnergy_(
config.getParameter<double>(
"MinEnergy")),
374 maxPseudoRapidity_(
config.getParameter<double>(
"MaxPseudoRapidity")),
375 premixStage1_(
config.getParameter<
bool>(
"premixStage1")),
381 producesCollector.
produces<std::vector<std::pair<unsigned int, float>>>(
"MergedCaloTruth");
392 std::vector<std::string> parameterNames = simHitCollectionConfig.getParameterNames();
394 for (
auto const ¶meterName : parameterNames) {
395 std::vector<edm::InputTag>
tags = simHitCollectionConfig.getParameter<std::vector<edm::InputTag>>(parameterName);
400 iC.
consumes<std::vector<PCaloHit>>(collectionTag);
417 eegeom = static_cast<const HGCalGeometry *>(
422 fhgeom = static_cast<const HGCalGeometry *>(
424 bhgeomnew = static_cast<const HGCalGeometry *>(
433 hgtopo_[1] = &(fhgeom->topology());
435 hgtopo_[2] = &(bhgeomnew->topology());
437 for (
unsigned i = 0;
i < 3; ++
i) {
472 <<
event.bunchCrossing();
489 auto totalEnergies = std::make_unique<std::vector<std::pair<unsigned int, float>>>();
492 std::sort(totalEnergies->begin(), totalEnergies->end());
493 event.put(
std::move(totalEnergies),
"MergedCaloTruth");
496 auto hitsAndEnergies = sc.hits_and_fractions();
497 sc.clearHitsAndFractions();
498 sc.clearHitsEnergy();
499 for (
auto &hAndE : hitsAndEnergies) {
503 fraction = hAndE.second / totalenergy;
506 <<
"TotalSimEnergy for hit " << hAndE.first <<
" is 0! The fraction for this hit cannot be computed.";
507 sc.addRecHitAndFraction(hAndE.first,
fraction);
508 sc.addHitEnergy(hAndE.second);
521 cp.addSimCluster(ref);
546 std::vector<std::pair<DetId, const PCaloHit *>> simHitPointers;
547 std::unordered_map<int, std::map<int, float>> simTrackDetIdEnergyMap;
552 for (
unsigned int i = 0;
i < simHitPointers.size(); ++
i) {
558 std::unordered_map<int, int> trackid_to_track_index;
565 trackid_to_track_index[
t.trackId()] =
idx;
596 std::vector<int> used_sim_tracks(
tracks.size(), 0);
597 std::vector<int> collapsed_vertices(
vertices.size(), 0);
601 if (
v.parentIndex() != -1) {
602 auto trk_idx = trackid_to_track_index[
v.parentIndex()];
603 auto origin_vtx =
tracks[trk_idx].vertIndex();
604 if (used_sim_tracks[trk_idx]) {
608 collapsed_vertices[
v.vertexId()] = used_sim_tracks[trk_idx];
612 if (collapsed_vertices[origin_vtx])
613 origin_vtx = collapsed_vertices[origin_vtx];
618 used_sim_tracks[trk_idx] =
v.vertexId();
622 auto const &vertexMothersProp =
get(vertex_name,
decay);
626 for (
size_t i = 0;
i <
tracks.size(); ++
i) {
627 if (!used_sim_tracks[
i]) {
628 auto origin_vtx =
tracks[
i].vertIndex();
630 if (collapsed_vertices[origin_vtx])
631 origin_vtx = collapsed_vertices[origin_vtx];
642 if (
v.parentIndex() != -1) {
644 if (collapsed_vertices[
v.vertexId()])
649 SimHitsAccumulator_dfs_visitor
vis;
650 depth_first_search(
decay, visitor(
vis));
651 CaloParticle_dfs_visitor caloParticleCreator(
655 simTrackDetIdEnergyMap,
665 depth_first_search(
decay, visitor(caloParticleCreator));
670 make_label_writer(make_transform_value_property_map(&graphviz_vertex,
get(vertex_name,
decay))),
671 make_label_writer(make_transform_value_property_map(&graphviz_edge,
get(edge_weight,
decay))));
677 std::unordered_map<
int, std::map<int, float>> &simTrackDetIdEnergyMap,
682 const bool isHcal = (collectionTag.instance().find(
"HcalHits") != std::string::npos);
683 event.getByLabel(collectionTag, hSimHits);
685 for (
auto const &
simHit : *hSimHits) {
690 const uint32_t simId =
simHit.id();
699 int subdet,
layer, cell,
sec, subsec, zp;
703 cell = recoLayerCell.first;
704 layer = recoLayerCell.second;
719 if (
id ==
DetId(0)) {
722 if (
simHit.geantTrackId() == 0) {
726 returnValue.emplace_back(
id, &
simHit);
727 simTrackDetIdEnergyMap[
simHit.geantTrackId()][
id.rawId()] +=
simHit.energy();