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>;
137 void accumulateEvent(
const T &event,
144 void fillSimHits(std::vector<std::pair<DetId, const PCaloHit *>> &returnValue,
145 std::unordered_map<
int, std::map<int, float>> &simTrackDetIdEnergyMap,
214 template <
typename Edge,
typename Graph,
typename Visitor>
215 void accumulateSimHits_edge(Edge &
e,
const Graph &
g, Visitor *
v) {
216 auto const edge_property =
get(edge_weight,
g,
e);
217 v->total_simHits += edge_property.simHits;
219 <<
" Examining edges " << e <<
" --> particle " << edge_property.simTrack->type() <<
"(" 220 << edge_property.simTrack->trackId() <<
")" 221 <<
" with SimClusters: " << edge_property.simHits <<
" Accumulated SimClusters: " << v->total_simHits
224 template <
typename Vertex,
typename Graph>
225 void print_vertex(Vertex &u,
const Graph &g) {
226 auto const vertex_property =
get(vertex_name,
g, u);
229 if (vertex_property.simTrack)
230 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
" [" << vertex_property.simTrack->type() <<
"]" 231 <<
"(" << vertex_property.simTrack->trackId() <<
")";
238 std::ostringstream oss;
245 std::ostringstream oss;
252 class SimHitsAccumulator_dfs_visitor :
public boost::default_dfs_visitor {
254 int total_simHits = 0;
255 template <
typename Edge,
typename Graph>
256 void examine_edge(Edge e,
const Graph &g) {
257 accumulateSimHits_edge(e, g,
this);
259 template <
typename Edge,
typename Graph>
260 void finish_edge(Edge e,
const Graph &g) {
261 auto const edge_property =
get(edge_weight,
g,
e);
268 auto const src_vertex_property =
get(vertex_name,
g,
src);
270 put(
get(edge_weight, const_cast<Graph &>(g)),
274 <<
" Finished edge: " << e <<
" Track id: " <<
get(edge_weight,
g,
e).
simTrack->
trackId()
275 <<
" has accumulated " <<
cumulative <<
" hits" << std::endl;
277 <<
"\t" <<
get(vertex_name, g,
src).cumulative_simHits << std::endl;
279 <<
"\t" <<
get(vertex_name, g,
trg).cumulative_simHits << std::endl;
283 using Selector = std::function<bool(EdgeProperty &)>;
285 class CaloParticle_dfs_visitor :
public boost::default_dfs_visitor {
289 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex,
290 std::unordered_map<
int, std::map<int, float>> &simTrackDetIdEnergyMap,
293 caloParticles_(caloParticles),
294 simHitBarcodeToIndex_(simHitBarcodeToIndex),
295 simTrackDetIdEnergyMap_(simTrackDetIdEnergyMap),
296 selector_(selector) {}
297 template <
typename Vertex,
typename Graph>
298 void discover_vertex(Vertex u,
const Graph &g) {
303 auto const vertex_property =
get(vertex_name,
g, u);
304 if (!vertex_property.simTrack)
306 auto trackIdx = vertex_property.simTrack->trackId();
308 <<
" Found " << simHitBarcodeToIndex_.count(trackIdx) <<
" associated simHits" << std::endl;
309 if (simHitBarcodeToIndex_.count(trackIdx)) {
310 output_.pSimClusters->emplace_back(*vertex_property.simTrack);
311 auto &simcluster = output_.pSimClusters->back();
312 std::unordered_map<uint32_t, float> acc_energy;
313 for (
auto const &hit_and_energy : simTrackDetIdEnergyMap_[trackIdx]) {
314 acc_energy[hit_and_energy.first] += hit_and_energy.second;
316 for (
auto const &hit_and_energy : acc_energy) {
317 simcluster.addRecHitAndFraction(hit_and_energy.first, hit_and_energy.second);
321 template <
typename Edge,
typename Graph>
322 void examine_edge(Edge e,
const Graph &g) {
324 auto vertex_property =
get(vertex_name,
g,
src);
325 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
326 auto edge_property =
get(edge_weight,
g,
e);
327 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
"Considering CaloParticle: " << edge_property.simTrack->trackId();
328 if (selector_(edge_property)) {
329 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
"Adding CaloParticle: " << edge_property.simTrack->trackId();
330 output_.pCaloParticles->emplace_back(*(edge_property.simTrack));
331 caloParticles_.sc_start_.push_back(output_.pSimClusters->size());
336 template <
typename Edge,
typename Graph>
337 void finish_edge(Edge e,
const Graph &g) {
339 auto vertex_property =
get(vertex_name,
g,
src);
340 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
341 auto edge_property =
get(edge_weight,
g,
e);
342 if (selector_(edge_property)) {
343 caloParticles_.sc_stop_.push_back(output_.pSimClusters->size());
351 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex_;
352 std::unordered_map<int, std::map<int, float>> &simTrackDetIdEnergyMap_;
360 : messageCategory_(
"CaloTruthAccumulator"),
361 maximumPreviousBunchCrossing_(config.getParameter<unsigned
int>(
"maximumPreviousBunchCrossing")),
362 maximumSubsequentBunchCrossing_(config.getParameter<unsigned
int>(
"maximumSubsequentBunchCrossing")),
363 simTrackLabel_(config.getParameter<
edm::InputTag>(
"simTrackCollection")),
364 simVertexLabel_(config.getParameter<
edm::InputTag>(
"simVertexCollection")),
366 genParticleLabel_(config.getParameter<
edm::InputTag>(
"genParticleCollection")),
367 hepMCproductLabel_(config.getParameter<
edm::InputTag>(
"HepMCProductLabel")),
368 minEnergy_(config.getParameter<double>(
"MinEnergy")),
369 maxPseudoRapidity_(config.getParameter<double>(
"MaxPseudoRapidity")),
370 premixStage1_(config.getParameter<
bool>(
"premixStage1")),
375 mixMod.
produces<std::vector<std::pair<unsigned int, float>>>(
"MergedCaloTruth");
386 std::vector<std::string> parameterNames = simHitCollectionConfig.
getParameterNames();
388 for (
auto const ¶meterName : parameterNames) {
389 std::vector<edm::InputTag> tags = simHitCollectionConfig.getParameter<std::vector<edm::InputTag>>(parameterName);
394 iC.
consumes<std::vector<PCaloHit>>(collectionTag);
401 const HGCalGeometry *eegeom =
nullptr, *fhgeom =
nullptr, *bhgeomnew =
nullptr;
420 hgtopo_[1] = &(fhgeom->topology());
422 hgtopo_[2] = &(bhgeomnew->topology());
424 for (
unsigned i = 0;
i < 3; ++
i) {
463 <<
event.bunchCrossing();
480 auto totalEnergies = std::make_unique<std::vector<std::pair<unsigned int, float>>>();
483 std::sort(totalEnergies->begin(), totalEnergies->end());
484 event.put(
std::move(totalEnergies),
"MergedCaloTruth");
489 for (
auto &hAndE : hitsAndEnergies) {
493 fraction = hAndE.second / totalenergy;
496 <<
"TotalSimEnergy for hit " << hAndE.first <<
" is 0! The fraction for this hit cannot be computed.";
535 std::vector<std::pair<DetId, const PCaloHit *>> simHitPointers;
536 std::unordered_map<int, std::map<int, float>> simTrackDetIdEnergyMap;
537 fillSimHits(simHitPointers, simTrackDetIdEnergyMap, event, setup);
541 for (
unsigned int i = 0;
i < simHitPointers.size(); ++
i) {
547 std::unordered_map<int, int> trackid_to_track_index;
554 trackid_to_track_index[
t.trackId()] =
idx;
585 std::vector<int> used_sim_tracks(tracks.size(), 0);
586 std::vector<int> collapsed_vertices(
vertices.size(), 0);
590 if (
v.parentIndex() != -1) {
591 auto trk_idx = trackid_to_track_index[
v.parentIndex()];
592 auto origin_vtx = tracks[trk_idx].vertIndex();
593 if (used_sim_tracks[trk_idx]) {
597 collapsed_vertices[
v.vertexId()] = used_sim_tracks[trk_idx];
601 if (collapsed_vertices[origin_vtx])
602 origin_vtx = collapsed_vertices[origin_vtx];
605 EdgeProperty(&tracks[trk_idx], simTrackDetIdEnergyMap[
v.parentIndex()].size(), 0),
607 used_sim_tracks[trk_idx] =
v.vertexId();
611 auto const &vertexMothersProp =
get(vertex_name,
decay);
614 int offset = vertices.size();
615 for (
size_t i = 0;
i < tracks.size(); ++
i) {
616 if (!used_sim_tracks[
i]) {
617 auto origin_vtx = tracks[
i].vertIndex();
619 if (collapsed_vertices[origin_vtx])
620 origin_vtx = collapsed_vertices[origin_vtx];
622 origin_vtx, offset,
EdgeProperty(&tracks[i], simTrackDetIdEnergyMap[tracks[i].trackId()].
size(), 0), decay);
630 for (
auto const &
v : vertices) {
631 if (
v.parentIndex() != -1) {
633 if (collapsed_vertices[
v.vertexId()])
635 put(vertexMothersProp,
v.vertexId(),
VertexProperty(&tracks[trackid_to_track_index[
v.parentIndex()]], 0));
638 SimHitsAccumulator_dfs_visitor
vis;
639 depth_first_search(decay, visitor(vis));
640 CaloParticle_dfs_visitor caloParticleCreator(
644 simTrackDetIdEnergyMap,
654 depth_first_search(decay, visitor(caloParticleCreator));
659 make_label_writer(make_transform_value_property_map(&graphviz_vertex,
get(vertex_name, decay))),
660 make_label_writer(make_transform_value_property_map(&graphviz_edge,
get(edge_weight, decay))));
666 std::unordered_map<
int, std::map<int, float>> &simTrackDetIdEnergyMap,
671 const bool isHcal = (collectionTag.instance().find(
"HcalHits") != std::string::npos);
672 event.getByLabel(collectionTag, hSimHits);
673 for (
auto const &
simHit : *hSimHits) {
675 const uint32_t simId =
simHit.id();
684 int subdet, layer, cell, sec, subsec, zp;
687 std::pair<int, int> recoLayerCell = ddd->
simToReco(cell, layer, sec,
hgtopo_[subdet - 3]->detectorType());
688 cell = recoLayerCell.first;
689 layer = recoLayerCell.second;
691 if (layer == -1 ||
simHit.geantTrackId() == 0)
699 uint32_t detId =
id.rawId();
700 returnValue.emplace_back(
id, &
simHit);
701 simTrackDetIdEnergyMap[
simHit.geantTrackId()][
id.rawId()] +=
simHit.energy();
BranchAliasSetterT< ProductType > produces()
declare what type of product will make and with which optional label
int bunchCrossing() const
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
std::unordered_multimap< Barcode_t, Index_t > m_simHitBarcodeToIndex
calo_particles m_caloParticles
const HcalDDDRecConstants * dddConstants() const
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
HcalSubdetector subdet() const
get the subdetector
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
const HGCalTopology * hgtopo_[3]
const unsigned int maximumSubsequentBunchCrossing_
void swap(calo_particles &oth)
void beginLuminosityBlock(edm::LuminosityBlock const &lumi, edm::EventSetup const &setup) override
def setup(process, global_tag, zero_tesla=False)
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 addRecHitAndFraction(uint32_t hit, float fraction)
add rechit with fraction
void swap(Association< C > &lhs, Association< C > &rhs)
const SimTrack * simTrack
const HcalTopology & topology() const
void put(edm::Event &evt, double value, const char *instanceName)
U second(std::pair< T, U > const &p)
const SimTrack * simTrack
edm::InputTag hepMCproductLabel_
Needed to add HepMC::GenVertex to SimVertex.
const std::string messageCategory_
std::pair< int, int > simToReco(int cell, int layer, int mod, bool half) const
void accumulate(const edm::Event &event, const edm::EventSetup &setup) override
const double maxPseudoRapidity_
CaloTruthAccumulator(const edm::ParameterSet &config, edm::ProducerBase &mixMod, edm::ConsumesCollector &iC)
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
const HGCalTopology & topology() const
void clearHitsAndFractions()
clear the hits and fractions list
Abs< T >::type abs(const T &t)
property< edge_weight_t, EdgeProperty > EdgeParticleClustersProperty
std::unordered_map< Index_t, float > m_detIdToTotalSimEnergy
const edm::InputTag simVertexLabel_
void addSimCluster(const SimClusterRef &ref)
std::vector< std::string > getParameterNames() const
Functor that operates on <T>
const HGCalDDDConstants * hgddd_[3]
VertexProperty(const VertexProperty &other)
const edm::InputTag simTrackLabel_
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.
unsigned int trackId() const
std::unique_ptr< CaloParticleCollection > pCaloParticles
const HGCalDDDConstants & dddConstants() const
ParameterSet const & getParameterSet(std::string const &) const
std::vector< uint32_t > sc_stop_
const HcalDDDRecConstants * hcddd_
void finalizeEvent(edm::Event &event, const edm::EventSetup &setup) override
int type() const
particle type (HEP PDT convension)
#define DEFINE_DIGI_ACCUMULATOR(type)
std::vector< CaloParticle > CaloParticleCollection
const math::XYZTLorentzVectorD & momentum() const
std::vector< uint32_t > sc_start_
property< vertex_name_t, VertexProperty > VertexMotherParticleProperty
std::unique_ptr< SimClusterCollection > pSimClusters
DetId relabel(const uint32_t testId) const
std::vector< SimCluster > SimClusterCollection
adjacency_list< listS, vecS, directedS, VertexMotherParticleProperty, EdgeParticleClustersProperty > DecayChain
static std::string const source
static void unpackHexagonIndex(const uint32_t &idx, int &subdet, int &z, int &lay, int &wafer, int &celltyp, int &cell)
#define IfLogDebug(cond, cat)
std::vector< std::pair< uint32_t, float > > hits_and_fractions() const
Returns list of rechit IDs and fractions for this SimCluster.
const unsigned int maximumPreviousBunchCrossing_