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>;
147 std::unordered_map<
int, std::map<int, float>> &simTrackDetIdEnergyMap,
217 template <
typename Edge,
typename Graph,
typename Visitor>
218 void accumulateSimHits_edge(Edge &
e,
const Graph &
g, Visitor *
v) {
219 auto const edge_property =
get(edge_weight,
g,
e);
220 v->total_simHits += edge_property.simHits;
222 <<
" Examining edges " <<
e <<
" --> particle " << edge_property.simTrack->type() <<
"("
223 << edge_property.simTrack->trackId() <<
")"
224 <<
" with SimClusters: " << edge_property.simHits <<
" Accumulated SimClusters: " <<
v->total_simHits
227 template <
typename Vertex,
typename Graph>
229 auto const vertex_property =
get(vertex_name,
g, u);
232 if (vertex_property.simTrack)
233 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
" [" << vertex_property.simTrack->type() <<
"]"
234 <<
"(" << vertex_property.simTrack->trackId() <<
")";
241 std::ostringstream oss;
242 oss <<
"{id: " << (
v.simTrack ?
v.simTrack->trackId() : 0) <<
",\\ntype: " << (
v.simTrack ?
v.simTrack->type() : 0)
243 <<
",\\nchits: " <<
v.cumulative_simHits <<
"}";
248 std::ostringstream oss;
249 oss <<
"[" << (
e.simTrack ?
e.simTrack->trackId() : 0) <<
"," << (
e.simTrack ?
e.simTrack->type() : 0) <<
","
250 <<
e.simHits <<
"," <<
e.cumulative_simHits <<
"]";
255 class SimHitsAccumulator_dfs_visitor :
public boost::default_dfs_visitor {
257 int total_simHits = 0;
258 template <
typename Edge,
typename Graph>
259 void examine_edge(Edge
e,
const Graph &
g) {
260 accumulateSimHits_edge(
e,
g,
this);
262 template <
typename Edge,
typename Graph>
263 void finish_edge(Edge
e,
const Graph &
g) {
264 auto const edge_property =
get(edge_weight,
g,
e);
267 auto cumulative = edge_property.simHits +
get(vertex_name,
g, trg).cumulative_simHits +
268 (
get(vertex_name,
g,
src).simTrack ?
get(vertex_name,
g,
src).cumulative_simHits
271 auto const src_vertex_property =
get(vertex_name,
g,
src);
273 put(
get(edge_weight, const_cast<Graph &>(
g)),
277 <<
" Finished edge: " <<
e <<
" Track id: " <<
get(edge_weight,
g,
e).simTrack->trackId()
278 <<
" has accumulated " <<
cumulative <<
" hits" << std::endl;
280 <<
"\t" <<
get(vertex_name,
g,
src).cumulative_simHits << std::endl;
281 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
" TrgVtx: " << trg <<
"\t" <<
get(vertex_name,
g, trg).simTrack
282 <<
"\t" <<
get(vertex_name,
g, trg).cumulative_simHits << std::endl;
288 class CaloParticle_dfs_visitor :
public boost::default_dfs_visitor {
292 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex,
293 std::unordered_map<
int, std::map<int, float>> &simTrackDetIdEnergyMap,
297 simHitBarcodeToIndex_(simHitBarcodeToIndex),
298 simTrackDetIdEnergyMap_(simTrackDetIdEnergyMap),
299 selector_(selector) {}
300 template <
typename Vertex,
typename Graph>
306 auto const vertex_property =
get(vertex_name,
g, u);
307 if (!vertex_property.simTrack)
309 auto trackIdx = vertex_property.simTrack->trackId();
311 <<
" Found " << simHitBarcodeToIndex_.count(trackIdx) <<
" associated simHits" << std::endl;
312 if (simHitBarcodeToIndex_.count(trackIdx)) {
313 output_.pSimClusters->emplace_back(*vertex_property.simTrack);
314 auto &simcluster = output_.pSimClusters->back();
315 std::unordered_map<uint32_t, float> acc_energy;
316 for (
auto const &hit_and_energy : simTrackDetIdEnergyMap_[trackIdx]) {
317 acc_energy[hit_and_energy.first] += hit_and_energy.second;
319 for (
auto const &hit_and_energy : acc_energy) {
320 simcluster.addRecHitAndFraction(hit_and_energy.first, hit_and_energy.second);
324 template <
typename Edge,
typename Graph>
325 void examine_edge(Edge
e,
const Graph &
g) {
327 auto vertex_property =
get(vertex_name,
g,
src);
328 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
329 auto edge_property =
get(edge_weight,
g,
e);
330 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
"Considering CaloParticle: " << edge_property.simTrack->trackId();
331 if (selector_(edge_property)) {
332 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
"Adding CaloParticle: " << edge_property.simTrack->trackId();
333 output_.pCaloParticles->emplace_back(*(edge_property.simTrack));
334 caloParticles_.sc_start_.push_back(output_.pSimClusters->size());
339 template <
typename Edge,
typename Graph>
340 void finish_edge(Edge
e,
const Graph &
g) {
342 auto vertex_property =
get(vertex_name,
g,
src);
343 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
344 auto edge_property =
get(edge_weight,
g,
e);
345 if (selector_(edge_property)) {
346 caloParticles_.sc_stop_.push_back(output_.pSimClusters->size());
354 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex_;
355 std::unordered_map<int, std::map<int, float>> &simTrackDetIdEnergyMap_;
363 : messageCategory_(
"CaloTruthAccumulator"),
364 maximumPreviousBunchCrossing_(
config.getParameter<unsigned
int>(
"maximumPreviousBunchCrossing")),
365 maximumSubsequentBunchCrossing_(
config.getParameter<unsigned
int>(
"maximumSubsequentBunchCrossing")),
371 minEnergy_(
config.getParameter<double>(
"MinEnergy")),
372 maxPseudoRapidity_(
config.getParameter<double>(
"MaxPseudoRapidity")),
373 premixStage1_(
config.getParameter<
bool>(
"premixStage1")),
379 producesCollector.
produces<std::vector<std::pair<unsigned int, float>>>(
"MergedCaloTruth");
390 std::vector<std::string> parameterNames = simHitCollectionConfig.getParameterNames();
392 for (
auto const ¶meterName : parameterNames) {
393 std::vector<edm::InputTag>
tags = simHitCollectionConfig.getParameter<std::vector<edm::InputTag>>(parameterName);
398 iC.
consumes<std::vector<PCaloHit>>(collectionTag);
410 eegeom = static_cast<const HGCalGeometry *>(
415 fhgeom = static_cast<const HGCalGeometry *>(
417 bhgeomnew = static_cast<const HGCalGeometry *>(
426 hgtopo_[1] = &(fhgeom->topology());
428 hgtopo_[2] = &(bhgeomnew->topology());
430 for (
unsigned i = 0;
i < 3; ++
i) {
471 <<
event.bunchCrossing();
488 auto totalEnergies = std::make_unique<std::vector<std::pair<unsigned int, float>>>();
491 std::sort(totalEnergies->begin(), totalEnergies->end());
492 event.put(
std::move(totalEnergies),
"MergedCaloTruth");
495 auto hitsAndEnergies = sc.hits_and_fractions();
496 sc.clearHitsAndFractions();
497 sc.clearHitsEnergy();
498 for (
auto &hAndE : hitsAndEnergies) {
502 fraction = hAndE.second / totalenergy;
505 <<
"TotalSimEnergy for hit " << hAndE.first <<
" is 0! The fraction for this hit cannot be computed.";
506 sc.addRecHitAndFraction(hAndE.first,
fraction);
507 sc.addHitEnergy(hAndE.second);
520 cp.addSimCluster(ref);
545 std::vector<std::pair<DetId, const PCaloHit *>> simHitPointers;
546 std::unordered_map<int, std::map<int, float>> simTrackDetIdEnergyMap;
551 for (
unsigned int i = 0;
i < simHitPointers.size(); ++
i) {
557 std::unordered_map<int, int> trackid_to_track_index;
564 trackid_to_track_index[
t.trackId()] =
idx;
595 std::vector<int> used_sim_tracks(
tracks.size(), 0);
596 std::vector<int> collapsed_vertices(
vertices.size(), 0);
600 if (
v.parentIndex() != -1) {
601 auto trk_idx = trackid_to_track_index[
v.parentIndex()];
602 auto origin_vtx =
tracks[trk_idx].vertIndex();
603 if (used_sim_tracks[trk_idx]) {
607 collapsed_vertices[
v.vertexId()] = used_sim_tracks[trk_idx];
611 if (collapsed_vertices[origin_vtx])
612 origin_vtx = collapsed_vertices[origin_vtx];
617 used_sim_tracks[trk_idx] =
v.vertexId();
621 auto const &vertexMothersProp =
get(vertex_name,
decay);
625 for (
size_t i = 0;
i <
tracks.size(); ++
i) {
626 if (!used_sim_tracks[
i]) {
627 auto origin_vtx =
tracks[
i].vertIndex();
629 if (collapsed_vertices[origin_vtx])
630 origin_vtx = collapsed_vertices[origin_vtx];
641 if (
v.parentIndex() != -1) {
643 if (collapsed_vertices[
v.vertexId()])
648 SimHitsAccumulator_dfs_visitor
vis;
649 depth_first_search(
decay, visitor(
vis));
650 CaloParticle_dfs_visitor caloParticleCreator(
654 simTrackDetIdEnergyMap,
664 depth_first_search(
decay, visitor(caloParticleCreator));
669 make_label_writer(make_transform_value_property_map(&graphviz_vertex,
get(vertex_name,
decay))),
670 make_label_writer(make_transform_value_property_map(&graphviz_edge,
get(edge_weight,
decay))));
676 std::unordered_map<
int, std::map<int, float>> &simTrackDetIdEnergyMap,
681 const bool isHcal = (collectionTag.instance().find(
"HcalHits") != std::string::npos);
682 event.getByLabel(collectionTag, hSimHits);
684 for (
auto const &
simHit : *hSimHits) {
689 const uint32_t simId =
simHit.id();
698 int subdet,
layer, cell,
sec, subsec, zp;
702 cell = recoLayerCell.first;
703 layer = recoLayerCell.second;
718 if (
id ==
DetId(0)) {
721 if (
simHit.geantTrackId() == 0) {
725 returnValue.emplace_back(
id, &
simHit);
726 simTrackDetIdEnergyMap[
simHit.geantTrackId()][
id.rawId()] +=
simHit.energy();