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
21 #include <unordered_map>
60 using Index_t = unsigned;
61 using Barcode_t =
int;
62 const std::string messageCategoryGraph_(
"CaloTruthAccumulatorGraphProducer");
65 using boost::add_edge;
66 using boost::adjacency_list;
67 using boost::directedS;
69 using boost::edge_weight;
70 using boost::edge_weight_t;
72 using boost::property;
75 using boost::vertex_name;
76 using boost::vertex_name_t;
122 using DecayChain = adjacency_list<listS, vecS, directedS, VertexMotherParticleProperty, EdgeParticleClustersProperty>;
144 void fillSimHits(std::vector<std::pair<DetId, const PCaloHit *>> &returnValue,
145 std::unordered_map<
int, std::map<int, float>> &simTrackDetIdEnergyMap,
215 template <
typename Edge,
typename Graph,
typename Visitor>
216 void accumulateSimHits_edge(Edge &
e,
const Graph &
g, Visitor *
v) {
217 auto const edge_property =
get(edge_weight,
g,
e);
218 v->total_simHits += edge_property.simHits;
220 <<
" Examining edges " <<
e <<
" --> particle " << edge_property.simTrack->type() <<
"("
221 << edge_property.simTrack->trackId() <<
")"
222 <<
" with SimClusters: " << edge_property.simHits <<
" Accumulated SimClusters: " <<
v->total_simHits
225 template <
typename Vertex,
typename Graph>
227 auto const vertex_property =
get(vertex_name,
g, u);
230 if (vertex_property.simTrack)
231 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
" [" << vertex_property.simTrack->type() <<
"]"
232 <<
"(" << vertex_property.simTrack->trackId() <<
")";
239 std::ostringstream oss;
240 oss <<
"{id: " << (
v.simTrack ?
v.simTrack->trackId() : 0) <<
",\\ntype: " << (
v.simTrack ?
v.simTrack->type() : 0)
241 <<
",\\nchits: " <<
v.cumulative_simHits <<
"}";
246 std::ostringstream oss;
247 oss <<
"[" << (
e.simTrack ?
e.simTrack->trackId() : 0) <<
"," << (
e.simTrack ?
e.simTrack->type() : 0) <<
","
248 <<
e.simHits <<
"," <<
e.cumulative_simHits <<
"]";
253 class SimHitsAccumulator_dfs_visitor :
public boost::default_dfs_visitor {
255 int total_simHits = 0;
256 template <
typename Edge,
typename Graph>
257 void examine_edge(Edge
e,
const Graph &
g) {
258 accumulateSimHits_edge(
e,
g,
this);
260 template <
typename Edge,
typename Graph>
261 void finish_edge(Edge
e,
const Graph &
g) {
262 auto const edge_property =
get(edge_weight,
g,
e);
265 auto cumulative = edge_property.simHits +
get(vertex_name,
g, trg).cumulative_simHits +
266 (
get(vertex_name,
g,
src).simTrack ?
get(vertex_name,
g,
src).cumulative_simHits
269 auto const src_vertex_property =
get(vertex_name,
g,
src);
271 put(
get(edge_weight, const_cast<Graph &>(
g)),
275 <<
" Finished edge: " <<
e <<
" Track id: " <<
get(edge_weight,
g,
e).simTrack->trackId()
276 <<
" has accumulated " <<
cumulative <<
" hits" << std::endl;
278 <<
"\t" <<
get(vertex_name,
g,
src).cumulative_simHits << std::endl;
279 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
" TrgVtx: " << trg <<
"\t" <<
get(vertex_name,
g, trg).simTrack
280 <<
"\t" <<
get(vertex_name,
g, trg).cumulative_simHits << std::endl;
286 class CaloParticle_dfs_visitor :
public boost::default_dfs_visitor {
290 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex,
291 std::unordered_map<
int, std::map<int, float>> &simTrackDetIdEnergyMap,
295 simHitBarcodeToIndex_(simHitBarcodeToIndex),
296 simTrackDetIdEnergyMap_(simTrackDetIdEnergyMap),
297 selector_(selector) {}
298 template <
typename Vertex,
typename Graph>
304 auto const vertex_property =
get(vertex_name,
g, u);
305 if (!vertex_property.simTrack)
307 auto trackIdx = vertex_property.simTrack->trackId();
309 <<
" Found " << simHitBarcodeToIndex_.count(trackIdx) <<
" associated simHits" << std::endl;
310 if (simHitBarcodeToIndex_.count(trackIdx)) {
311 output_.pSimClusters->emplace_back(*vertex_property.simTrack);
312 auto &simcluster = output_.pSimClusters->back();
313 std::unordered_map<uint32_t, float> acc_energy;
314 for (
auto const &hit_and_energy : simTrackDetIdEnergyMap_[trackIdx]) {
315 acc_energy[hit_and_energy.first] += hit_and_energy.second;
317 for (
auto const &hit_and_energy : acc_energy) {
318 simcluster.addRecHitAndFraction(hit_and_energy.first, hit_and_energy.second);
322 template <
typename Edge,
typename Graph>
323 void examine_edge(Edge
e,
const Graph &
g) {
325 auto vertex_property =
get(vertex_name,
g,
src);
326 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
327 auto edge_property =
get(edge_weight,
g,
e);
328 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
"Considering CaloParticle: " << edge_property.simTrack->trackId();
329 if (selector_(edge_property)) {
330 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
"Adding CaloParticle: " << edge_property.simTrack->trackId();
331 output_.pCaloParticles->emplace_back(*(edge_property.simTrack));
332 caloParticles_.sc_start_.push_back(output_.pSimClusters->size());
337 template <
typename Edge,
typename Graph>
338 void finish_edge(Edge
e,
const Graph &
g) {
340 auto vertex_property =
get(vertex_name,
g,
src);
341 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
342 auto edge_property =
get(edge_weight,
g,
e);
343 if (selector_(edge_property)) {
344 caloParticles_.sc_stop_.push_back(output_.pSimClusters->size());
352 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex_;
353 std::unordered_map<int, std::map<int, float>> &simTrackDetIdEnergyMap_;
361 : messageCategory_(
"CaloTruthAccumulator"),
362 maximumPreviousBunchCrossing_(
config.getParameter<unsigned
int>(
"maximumPreviousBunchCrossing")),
363 maximumSubsequentBunchCrossing_(
config.getParameter<unsigned
int>(
"maximumSubsequentBunchCrossing")),
369 minEnergy_(
config.getParameter<double>(
"MinEnergy")),
370 maxPseudoRapidity_(
config.getParameter<double>(
"MaxPseudoRapidity")),
371 premixStage1_(
config.getParameter<
bool>(
"premixStage1")),
377 producesCollector.
produces<std::vector<std::pair<unsigned int, float>>>(
"MergedCaloTruth");
388 std::vector<std::string> parameterNames = simHitCollectionConfig.getParameterNames();
390 for (
auto const ¶meterName : parameterNames) {
391 std::vector<edm::InputTag>
tags = simHitCollectionConfig.getParameter<std::vector<edm::InputTag>>(parameterName);
396 iC.
consumes<std::vector<PCaloHit>>(collectionTag);
408 eegeom = static_cast<const HGCalGeometry *>(
413 fhgeom = static_cast<const HGCalGeometry *>(
415 bhgeomnew = static_cast<const HGCalGeometry *>(
424 hgtopo_[1] = &(fhgeom->topology());
426 hgtopo_[2] = &(bhgeomnew->topology());
428 for (
unsigned i = 0;
i < 3; ++
i) {
469 <<
event.bunchCrossing();
486 auto totalEnergies = std::make_unique<std::vector<std::pair<unsigned int, float>>>();
489 std::sort(totalEnergies->begin(), totalEnergies->end());
490 event.put(
std::move(totalEnergies),
"MergedCaloTruth");
493 auto hitsAndEnergies = sc.hits_and_fractions();
494 sc.clearHitsAndFractions();
495 sc.clearHitsEnergy();
496 for (
auto &hAndE : hitsAndEnergies) {
500 fraction = hAndE.second / totalenergy;
503 <<
"TotalSimEnergy for hit " << hAndE.first <<
" is 0! The fraction for this hit cannot be computed.";
504 sc.addRecHitAndFraction(hAndE.first,
fraction);
505 sc.addHitEnergy(hAndE.second);
518 cp.addSimCluster(ref);
543 std::vector<std::pair<DetId, const PCaloHit *>> simHitPointers;
544 std::unordered_map<int, std::map<int, float>> simTrackDetIdEnergyMap;
549 for (
unsigned int i = 0;
i < simHitPointers.size(); ++
i) {
555 std::unordered_map<int, int> trackid_to_track_index;
562 trackid_to_track_index[
t.trackId()] =
idx;
593 std::vector<int> used_sim_tracks(
tracks.size(), 0);
594 std::vector<int> collapsed_vertices(
vertices.size(), 0);
598 if (
v.parentIndex() != -1) {
599 auto trk_idx = trackid_to_track_index[
v.parentIndex()];
600 auto origin_vtx =
tracks[trk_idx].vertIndex();
601 if (used_sim_tracks[trk_idx]) {
605 collapsed_vertices[
v.vertexId()] = used_sim_tracks[trk_idx];
609 if (collapsed_vertices[origin_vtx])
610 origin_vtx = collapsed_vertices[origin_vtx];
615 used_sim_tracks[trk_idx] =
v.vertexId();
619 auto const &vertexMothersProp =
get(vertex_name,
decay);
623 for (
size_t i = 0;
i <
tracks.size(); ++
i) {
624 if (!used_sim_tracks[
i]) {
625 auto origin_vtx =
tracks[
i].vertIndex();
627 if (collapsed_vertices[origin_vtx])
628 origin_vtx = collapsed_vertices[origin_vtx];
639 if (
v.parentIndex() != -1) {
641 if (collapsed_vertices[
v.vertexId()])
646 SimHitsAccumulator_dfs_visitor
vis;
647 depth_first_search(
decay, visitor(
vis));
648 CaloParticle_dfs_visitor caloParticleCreator(
652 simTrackDetIdEnergyMap,
662 depth_first_search(
decay, visitor(caloParticleCreator));
667 make_label_writer(make_transform_value_property_map(&graphviz_vertex,
get(vertex_name,
decay))),
668 make_label_writer(make_transform_value_property_map(&graphviz_edge,
get(edge_weight,
decay))));
674 std::unordered_map<
int, std::map<int, float>> &simTrackDetIdEnergyMap,
679 const bool isHcal = (collectionTag.instance().find(
"HcalHits") != std::string::npos);
680 event.getByLabel(collectionTag, hSimHits);
682 for (
auto const &
simHit : *hSimHits) {
687 const uint32_t simId =
simHit.id();
696 int subdet, layer, cell,
sec, subsec, zp;
699 std::pair<int, int> recoLayerCell = ddd->
simToReco(cell, layer,
sec,
hgtopo_[subdet - 3]->detectorType());
700 cell = recoLayerCell.first;
701 layer = recoLayerCell.second;
703 if (layer == -1 ||
simHit.geantTrackId() == 0)
716 if (
id ==
DetId(0)) {
719 if (
simHit.geantTrackId() == 0) {
723 returnValue.emplace_back(
id, &
simHit);
724 simTrackDetIdEnergyMap[
simHit.geantTrackId()][
id.rawId()] +=
simHit.energy();