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;
283 <<
"\t" <<
get(vertex_name,
g, trg).cumulative_simHits << std::endl;
287 using Selector = std::function<bool(EdgeProperty &)>;
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);
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();
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
std::unordered_multimap< Barcode_t, Index_t > m_simHitBarcodeToIndex
calo_particles m_caloParticles
edm::Handle< std::vector< SimVertex > > hSimVertices
void fillSimHits(std::vector< std::pair< DetId, const PCaloHit *>> &returnValue, std::unordered_map< int, std::map< int, float >> &simTrackDetIdEnergyMap, const T &event, const edm::EventSetup &setup)
Fills the supplied vector with pointers to the SimHits, checking for bad modules if required...
void initializeEvent(const edm::Event &event, const edm::EventSetup &setup) override
ProductRegistryHelper::BranchAliasSetterT< ProductType > produces()
const HGCalTopology * hgtopo_[3]
const unsigned int maximumSubsequentBunchCrossing_
void swap(calo_particles &oth)
std::vector< edm::InputTag > collectionTags_
edm::InputTag genParticleLabel_
EdgeProperty(const SimTrack *t, int h, int c)
OutputCollections output_
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
void swap(Association< C > &lhs, Association< C > &rhs)
const math::XYZTLorentzVectorD & momentum() const
const SimTrack * simTrack
constexpr std::array< uint8_t, layerIndexSize > layer
void put(edm::Event &evt, double value, const char *instanceName)
edm::ESWatcher< CaloGeometryRecord > geomWatcher_
U second(std::pair< T, U > const &p)
const SimTrack * simTrack
constexpr HcalSubdetector subdet() const
get the subdetector
edm::InputTag hepMCproductLabel_
Needed to add HepMC::GenVertex to SimVertex.
#define IfLogDebug(cond, cat)
const std::string messageCategory_
void accumulate(const edm::Event &event, const edm::EventSetup &setup) override
const double maxPseudoRapidity_
const edm::ESGetToken< CaloGeometry, CaloGeometryRecord > geomToken_
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Abs< T >::type abs(const T &t)
std::pair< int, int > simToReco(int cell, int layer, int mod, bool half) const
property< edge_weight_t, EdgeProperty > EdgeParticleClustersProperty
CaloTruthAccumulator(const edm::ParameterSet &config, edm::ProducesCollector, edm::ConsumesCollector &iC)
std::unordered_map< Index_t, float > m_detIdToTotalSimEnergy
const edm::InputTag simVertexLabel_
DetId relabel(const uint32_t testId) const
Functor that operates on <T>
const HGCalDDDConstants * hgddd_[3]
VertexProperty(const VertexProperty &other)
const edm::InputTag simTrackLabel_
Log< level::Info, false > LogInfo
VertexProperty(const SimTrack *t, int c)
edm::Handle< std::vector< SimTrack > > hSimTracks
void accumulateEvent(const T &event, const edm::EventSetup &setup, const edm::Handle< edm::HepMCProduct > &hepMCproduct)
Both forms of accumulate() delegate to this templated method.
auto const & tracks
cannot be loose
std::unique_ptr< CaloParticleCollection > pCaloParticles
std::vector< uint32_t > sc_stop_
const HcalDDDRecConstants * hcddd_
void finalizeEvent(edm::Event &event, const edm::EventSetup &setup) override
bool check(const edm::EventSetup &iSetup)
#define DEFINE_DIGI_ACCUMULATOR(type)
std::vector< CaloParticle > CaloParticleCollection
std::vector< uint32_t > sc_start_
property< vertex_name_t, VertexProperty > VertexMotherParticleProperty
const HcalDDDRecConstants * dddConstants() const
std::unique_ptr< SimClusterCollection > pSimClusters
Log< level::Warning, false > LogWarning
std::vector< SimCluster > SimClusterCollection
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
adjacency_list< listS, vecS, directedS, VertexMotherParticleProperty, EdgeParticleClustersProperty > DecayChain
static std::string const source
const HGCalDDDConstants & dddConstants() const
static void unpackHexagonIndex(const uint32_t &idx, int &subdet, int &z, int &lay, int &wafer, int &celltyp, int &cell)
const unsigned int maximumPreviousBunchCrossing_
const HcalTopology & topology() const