4 #pragma GCC diagnostic push 5 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" 9 #include <boost/graph/adjacency_list.hpp> 10 #include <boost/graph/breadth_first_search.hpp> 11 #include <boost/graph/depth_first_search.hpp> 12 #include <boost/graph/graphviz.hpp> 15 #pragma GCC diagnostic pop 20 #include <unordered_map> 59 using Index_t = unsigned;
60 using Barcode_t =
int;
61 const std::string messageCategoryGraph_(
"CaloTruthAccumulatorGraphProducer");
64 using boost::adjacency_list;
65 using boost::directedS;
68 using boost::property;
70 using boost::edge_weight_t;
71 using boost::edge_weight;
72 using boost::add_edge;
74 using boost::vertex_name_t;
75 using boost::vertex_name;
147 void fillSimHits(std::vector<std::pair<DetId, const PCaloHit*> >& returnValue,
148 std::unordered_map<
int, std::map<int, float> >& simTrackDetIdEnergyMap,
216 template <
typename Edge,
typename Graph,
typename Visitor>
217 void accumulateSimHits_edge(Edge&
e,
const Graph&
g, Visitor*
v) {
218 auto const edge_property =
get(edge_weight,
g,
e);
219 v->total_simHits += edge_property.simHits;
221 <<
" Examining edges " << e <<
" --> particle " << edge_property.simTrack->type() <<
"(" 222 << edge_property.simTrack->trackId() <<
")" 223 <<
" with SimClusters: " << edge_property.simHits
224 <<
" Accumulated SimClusters: " << v->total_simHits << std::endl;
226 template <
typename Vertex,
typename Graph>
227 void print_vertex(Vertex& u,
const Graph& g) {
228 auto const vertex_property =
get(vertex_name,
g, u);
231 if (vertex_property.simTrack)
232 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
" [" << vertex_property.simTrack->type() <<
"]" 233 <<
"(" << vertex_property.simTrack->trackId() <<
")";
240 std::ostringstream oss;
248 std::ostringstream oss;
257 class SimHitsAccumulator_dfs_visitor :
public boost::default_dfs_visitor {
259 int total_simHits = 0;
260 template <
typename Edge,
typename Graph>
261 void examine_edge(Edge e,
const Graph& g) {
262 accumulateSimHits_edge(e, g,
this);
264 template <
typename Edge,
typename Graph>
265 void finish_edge(Edge e,
const Graph& g) {
266 auto const edge_property =
get(edge_weight,
g,
e);
271 (
get(vertex_name, g,
src).simTrack
274 auto const src_vertex_property =
get(vertex_name,
g,
src);
275 put(
get(vertex_name, const_cast<Graph&>(g)),
src,
277 put(
get(edge_weight, const_cast<Graph&>(g)), e,
280 <<
" Finished edge: " << e <<
" Track id: " <<
get(edge_weight,
g,
e).
simTrack->
trackId()
281 <<
" has accumulated " <<
cumulative <<
" hits" << std::endl;
283 <<
" SrcVtx: " <<
src <<
"\t" <<
get(vertex_name,
g,
src).
simTrack <<
"\t" 284 <<
get(vertex_name, g,
src).cumulative_simHits << std::endl;
286 <<
" TrgVtx: " <<
trg <<
"\t" <<
get(vertex_name,
g,
trg).
simTrack <<
"\t" 287 <<
get(vertex_name, g,
trg).cumulative_simHits << std::endl;
291 using Selector = std::function<bool(EdgeProperty&)>;
293 class CaloParticle_dfs_visitor :
public boost::default_dfs_visitor {
297 std::unordered_multimap<Barcode_t, Index_t>& simHitBarcodeToIndex,
298 std::unordered_map<
int, std::map<int, float> >& simTrackDetIdEnergyMap,
301 caloParticles_(caloParticles),
302 simHitBarcodeToIndex_(simHitBarcodeToIndex),
303 simTrackDetIdEnergyMap_(simTrackDetIdEnergyMap),
304 selector_(selector) {}
305 template <
typename Vertex,
typename Graph>
306 void discover_vertex(Vertex u,
const Graph& g) {
311 auto const vertex_property =
get(vertex_name,
g, u);
312 if (!vertex_property.simTrack)
return;
313 auto trackIdx = vertex_property.simTrack->trackId();
315 <<
" Found " << simHitBarcodeToIndex_.count(trackIdx) <<
" associated simHits" << std::endl;
316 if (simHitBarcodeToIndex_.count(trackIdx)) {
317 output_.pSimClusters->emplace_back(*vertex_property.simTrack);
318 auto& simcluster = output_.pSimClusters->back();
319 std::unordered_map<uint32_t, float> acc_energy;
320 for (
auto const& hit_and_energy : simTrackDetIdEnergyMap_[trackIdx]) {
321 acc_energy[hit_and_energy.first] += hit_and_energy.second;
323 for (
auto const& hit_and_energy : acc_energy) {
324 simcluster.addRecHitAndFraction(hit_and_energy.first, hit_and_energy.second);
328 template <
typename Edge,
typename Graph>
329 void examine_edge(Edge e,
const Graph& g) {
331 auto vertex_property =
get(vertex_name,
g,
src);
332 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
333 auto edge_property =
get(edge_weight,
g,
e);
335 <<
"Considering CaloParticle: " << edge_property.simTrack->trackId();
336 if (selector_(edge_property)) {
338 <<
"Adding CaloParticle: " << edge_property.simTrack->trackId();
339 output_.pCaloParticles->emplace_back(*(edge_property.simTrack));
340 caloParticles_.sc_start_.push_back(output_.pSimClusters->size());
345 template <
typename Edge,
typename Graph>
346 void finish_edge(Edge e,
const Graph& g) {
348 auto vertex_property =
get(vertex_name,
g,
src);
349 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
350 auto edge_property =
get(edge_weight,
g,
e);
351 if (selector_(edge_property)) {
352 caloParticles_.sc_stop_.push_back(output_.pSimClusters->size());
360 std::unordered_multimap<Barcode_t, Index_t>& simHitBarcodeToIndex_;
361 std::unordered_map<int, std::map<int, float> >& simTrackDetIdEnergyMap_;
369 : messageCategory_(
"CaloTruthAccumulator"),
370 maximumPreviousBunchCrossing_(
371 config.getParameter<unsigned
int>(
"maximumPreviousBunchCrossing")),
372 maximumSubsequentBunchCrossing_(
373 config.getParameter<unsigned
int>(
"maximumSubsequentBunchCrossing")),
374 simTrackLabel_(config.getParameter<
edm::InputTag>(
"simTrackCollection")),
375 simVertexLabel_(config.getParameter<
edm::InputTag>(
"simVertexCollection")),
377 genParticleLabel_(config.getParameter<
edm::InputTag>(
"genParticleCollection")),
378 hepMCproductLabel_(config.getParameter<
edm::InputTag>(
"HepMCProductLabel")),
379 minEnergy_(config.getParameter<double>(
"MinEnergy")),
380 maxPseudoRapidity_(config.getParameter<double>(
"MaxPseudoRapidity")),
381 premixStage1_(config.getParameter<
bool>(
"premixStage1")),
387 mixMod.
produces<std::vector<std::pair<unsigned int, float> > >(
"MergedCaloTruth");
398 std::vector<std::string> parameterNames = simHitCollectionConfig.
getParameterNames();
400 for (
auto const& parameterName : parameterNames) {
401 std::vector<edm::InputTag> tags =
402 simHitCollectionConfig.getParameter<std::vector<edm::InputTag> >(parameterName);
407 iC.
consumes<std::vector<PCaloHit> >(collectionTag);
415 const HGCalGeometry *eegeom =
nullptr, *fhgeom =
nullptr, *bhgeomnew =
nullptr;
432 hgtopo_[1] = &(fhgeom->topology());
433 if(bhgeomnew)
hgtopo_[2] = &(bhgeomnew->topology());
435 for (
unsigned i = 0;
i < 3; ++
i) {
473 <<
" CaloTruthAccumulator::accumulate (pileup) bunchCrossing=" 474 <<
event.bunchCrossing();
478 <<
"Skipping pileup event for bunch crossing " <<
event.bunchCrossing();
485 <<
" CaloParticles to the event.";
492 auto totalEnergies = std::make_unique<std::vector<std::pair<unsigned int, float> > >();
495 std::sort(totalEnergies->begin(), totalEnergies->end());
496 event.put(
std::move(totalEnergies),
"MergedCaloTruth");
502 for (
auto& hAndE : hitsAndEnergies) {
506 fraction = hAndE.second / totalenergy;
509 <<
" is 0! The fraction for this hit cannot be computed.";
549 std::vector<std::pair<DetId, const PCaloHit*> > simHitPointers;
550 std::unordered_map<int, std::map<int, float> > simTrackDetIdEnergyMap;
551 fillSimHits(simHitPointers, simTrackDetIdEnergyMap, event, setup);
555 for (
unsigned int i = 0;
i < simHitPointers.size(); ++
i) {
561 std::unordered_map<int, int> trackid_to_track_index;
568 <<
" " << idx <<
"\t" <<
t.trackId() <<
"\t" <<
t << std::endl;
569 trackid_to_track_index[
t.trackId()] =
idx;
600 std::vector<int> used_sim_tracks(tracks.size(), 0);
601 std::vector<int> collapsed_vertices(
vertices.size(), 0);
605 if (
v.parentIndex() != -1) {
606 auto trk_idx = trackid_to_track_index[
v.parentIndex()];
607 auto origin_vtx = tracks[trk_idx].vertIndex();
608 if (used_sim_tracks[trk_idx]) {
612 collapsed_vertices[
v.vertexId()] = used_sim_tracks[trk_idx];
616 if (collapsed_vertices[origin_vtx]) origin_vtx = collapsed_vertices[origin_vtx];
617 add_edge(origin_vtx,
v.vertexId(),
618 EdgeProperty(&tracks[trk_idx], simTrackDetIdEnergyMap[
v.parentIndex()].size(), 0),
620 used_sim_tracks[trk_idx] =
v.vertexId();
624 auto const& vertexMothersProp =
get(vertex_name,
decay);
627 int offset = vertices.size();
628 for (
size_t i = 0;
i < tracks.size(); ++
i) {
629 if (!used_sim_tracks[
i]) {
630 auto origin_vtx = tracks[
i].vertIndex();
632 if (collapsed_vertices[origin_vtx]) origin_vtx = collapsed_vertices[origin_vtx];
633 add_edge(origin_vtx, offset,
634 EdgeProperty(&tracks[i], simTrackDetIdEnergyMap[tracks[i].trackId()].
size(), 0),
643 for (
auto const&
v : vertices) {
644 if (
v.parentIndex() != -1) {
646 if (collapsed_vertices[
v.vertexId()])
continue;
647 put(vertexMothersProp,
v.vertexId(),
651 SimHitsAccumulator_dfs_visitor
vis;
652 depth_first_search(decay, visitor(vis));
653 CaloParticle_dfs_visitor caloParticleCreator(
663 depth_first_search(decay, visitor(caloParticleCreator));
666 boost::write_graphviz(
std::cout, decay, make_label_writer(make_transform_value_property_map(
667 &graphviz_vertex,
get(vertex_name, decay))),
668 make_label_writer(make_transform_value_property_map(
669 &graphviz_edge,
get(edge_weight, decay))));
675 std::vector<std::pair<DetId, const PCaloHit*> >& returnValue,
676 std::unordered_map<
int, std::map<int, float> >& simTrackDetIdEnergyMap,
const T& event,
680 const bool isHcal = (collectionTag.instance().find(
"HcalHits") != std::string::npos);
681 event.getByLabel(collectionTag, hSimHits);
682 for (
auto const&
simHit : *hSimHits) {
684 const uint32_t simId =
simHit.id();
693 int subdet, layer, cell, sec, subsec, zp;
696 std::pair<int, int> recoLayerCell =
698 cell = recoLayerCell.first;
699 layer = recoLayerCell.second;
701 if (layer == -1 ||
simHit.geantTrackId() == 0)
continue;
705 if (
DetId(0) ==
id)
continue;
707 uint32_t detId =
id.rawId();
708 returnValue.emplace_back(
id, &
simHit);
709 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 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.
std::vector< std::pair< uint32_t, float > > hits_and_fractions() const
Returns list of rechit IDs and fractions for this SimCluster.
const HGCalTopology * hgtopo_[3]
const unsigned int maximumSubsequentBunchCrossing_
void swap(calo_particles &oth)
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 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)
const unsigned int maximumPreviousBunchCrossing_