7 #pragma GCC diagnostic pop 16 #include <unordered_map> 61 using Index_t = unsigned;
62 using Barcode_t =
int;
63 const std::string messageCategoryGraph_(
"MtdTruthAccumulatorGraphProducer");
86 std::unordered_map<
int, std::map<uint64_t, float>> &simTrackDetIdEnergyMap,
87 std::unordered_map<
int, std::map<uint64_t, float>> &simTrackDetIdTimeMap,
164 class CaloParticle_dfs_visitor :
public boost::default_dfs_visitor {
168 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex,
169 std::unordered_map<
int, std::map<uint64_t, float>> &simTrackDetIdEnergyMap,
170 std::unordered_map<
int, std::map<uint64_t, float>> &simTrackDetIdTimeMap,
171 std::unordered_map<uint32_t, float> &vertex_time_map,
175 simHitBarcodeToIndex_(simHitBarcodeToIndex),
176 simTrackDetIdEnergyMap_(simTrackDetIdEnergyMap),
177 simTrackDetIdTimeMap_(simTrackDetIdTimeMap),
178 vertex_time_map_(vertex_time_map),
179 selector_(selector) {}
180 template <
typename Vertex,
typename Graph>
186 auto const vertex_property =
get(vertex_name,
g, u);
187 if (!vertex_property.simTrack)
189 auto trackIdx = vertex_property.simTrack->trackId();
191 <<
" Found " << simHitBarcodeToIndex_.count(trackIdx) <<
" associated simHits" << std::endl;
192 if (simHitBarcodeToIndex_.count(trackIdx)) {
193 output_.pSimClusters->emplace_back(*vertex_property.simTrack);
194 auto &simcluster = output_.pSimClusters->back();
195 std::unordered_map<uint64_t, float> acc_energy;
196 for (
auto const &hit_and_energy : simTrackDetIdEnergyMap_[trackIdx]) {
197 acc_energy[hit_and_energy.first] += hit_and_energy.second;
199 for (
auto const &hit_and_energy : acc_energy) {
200 simcluster.addHitAndFraction(hit_and_energy.first, hit_and_energy.second);
201 simcluster.addHitEnergy(hit_and_energy.second);
202 simcluster.addHitTime(simTrackDetIdTimeMap_[simcluster.g4Tracks()[0].trackId()][hit_and_energy.first]);
206 template <
typename Edge,
typename Graph>
207 void examine_edge(Edge
e,
const Graph &
g) {
209 auto vertex_property =
get(vertex_name,
g,
src);
210 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
211 auto edge_property =
get(edge_weight,
g,
e);
212 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
"Considering CaloParticle: " << edge_property.simTrack->trackId();
213 if (selector_(edge_property)) {
214 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
"Adding CaloParticle: " << edge_property.simTrack->trackId();
215 output_.pCaloParticles->emplace_back(*(edge_property.simTrack));
216 output_.pCaloParticles->back().addSimTime(vertex_time_map_[(edge_property.simTrack)->vertIndex()]);
217 caloParticles_.sc_start_.push_back(output_.pSimClusters->size());
222 template <
typename Edge,
typename Graph>
223 void finish_edge(Edge
e,
const Graph &
g) {
225 auto vertex_property =
get(vertex_name,
g,
src);
226 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
227 auto edge_property =
get(edge_weight,
g,
e);
228 if (selector_(edge_property)) {
229 caloParticles_.sc_stop_.push_back(output_.pSimClusters->size());
237 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex_;
238 std::unordered_map<int, std::map<uint64_t, float>> &simTrackDetIdEnergyMap_;
239 std::unordered_map<int, std::map<uint64_t, float>> &simTrackDetIdTimeMap_;
240 std::unordered_map<uint32_t, float> &vertex_time_map_;
248 : messageCategory_(
"MtdTruthAccumulator"),
249 maximumPreviousBunchCrossing_(
config.getParameter<unsigned
int>(
"maximumPreviousBunchCrossing")),
250 maximumSubsequentBunchCrossing_(
config.getParameter<unsigned
int>(
"maximumSubsequentBunchCrossing")),
251 bunchSpacing_(
config.getParameter<unsigned
int>(
"bunchspace")),
259 minEnergy_(
config.getParameter<double>(
"MinEnergy")),
260 maxPseudoRapidity_(
config.getParameter<double>(
"MaxPseudoRapidity")),
261 premixStage1_(
config.getParameter<
bool>(
"premixStage1")) {
270 std::vector<std::string> parameterNames = simHitCollectionConfig.getParameterNames();
272 for (
auto const ¶meterName : parameterNames) {
273 std::vector<edm::InputTag>
tags = simHitCollectionConfig.getParameter<std::vector<edm::InputTag>>(parameterName);
278 iC.
consumes<std::vector<PSimHit>>(collectionTag);
279 isEtl_ = (collectionTag.instance().find(
"FastTimerHitsEndcap") != std::string::npos);
287 producesCollector.
produces<std::vector<std::pair<uint64_t, float>>>(
"MergedMtdTruth");
301 geom = geometryHandle.product();
304 topology = topologyHandle.product();
333 <<
event.bunchCrossing();
352 auto totalEnergies = std::make_unique<std::vector<std::pair<uint64_t, float>>>();
355 std::sort(totalEnergies->begin(), totalEnergies->end());
356 event.put(
std::move(totalEnergies),
"MergedMtdTruth");
359 auto hitsAndEnergies = sc.hits_and_fractions();
360 sc.clearHitsAndFractions();
361 sc.clearHitsEnergy();
362 for (
auto &hAndE : hitsAndEnergies) {
366 fraction = hAndE.second / totalenergy;
369 <<
"TotalSimEnergy for hit " << hAndE.first <<
" is 0! The fraction for this hit cannot be computed.";
370 sc.addHitAndFraction(hAndE.first,
fraction);
371 sc.addHitEnergy(hAndE.second);
380 <<
"\n charge " << sc.charge() <<
"\n pdgId " << sc.pdgId() <<
"\n energy " 381 << sc.energy() <<
" GeV\n eta " << sc.eta() <<
"\n phi " << sc.phi()
382 <<
"\n number of cells = " << sc.hits_and_fractions().size() << std::endl;
383 for (
unsigned int i = 0;
i < sc.hits_and_fractions().size(); ++
i) {
384 DetId id(sc.detIds_and_rows()[
i].first);
388 <<
" col " << (
unsigned int)(sc.detIds_and_rows()[
i].second).
second <<
" at time " 389 << sc.hits_and_times()[
i].second <<
" ns" << std::endl;
403 uint32_t SC_index = 0;
404 uint32_t LC_index = 0;
405 for (
const auto &sc : *scHandle) {
406 auto const &hAndF = sc.hits_and_fractions();
407 auto const &hAndE = sc.hits_and_energies();
408 auto const &hAndT = sc.hits_and_times();
409 auto const &hAndR = sc.detIds_and_rows();
411 std::vector<int>
indices(hAndF.size());
420 std::vector<uint32_t> LC_indices;
425 float SimLCenergy = 0.;
426 float SimLCx = 0., SimLCy = 0., SimLCz = 0.;
428 auto push_back_hit = [&](
const int &ind) {
429 tmpLC.addHitAndFraction(hAndF[ind].
first, hAndF[ind].
second);
430 tmpLC.addHitEnergy(hAndE[ind].
second);
431 tmpLC.addHitTime(hAndT[ind].
second);
434 auto update_clu_info = [&](
const int &ind) {
435 double energy = hAndE[ind].second;
444 auto push_back_clu = [&](
const uint32_t &SC_index, uint32_t &LC_index) {
445 tmpLC.addCluEnergy(SimLCenergy);
446 LocalPoint SimLCpos(SimLCx / SimLCenergy, SimLCy / SimLCenergy, SimLCz / SimLCenergy);
447 tmpLC.addCluLocalPos(SimLCpos);
452 tmpLC.addCluIndex(SC_index);
453 tmpLC.computeClusterTime();
455 LC_indices.push_back(LC_index);
462 update_clu_info(prev);
463 for (
const auto &ind :
indices) {
475 push_back_clu(SC_index, LC_index);
479 update_clu_info(ind);
485 push_back_clu(SC_index, LC_index);
490 float timeAtEntrance = 99.;
491 uint32_t idAtEntrance = 0;
492 for (uint32_t
i = 0;
i < (uint32_t)hAndT.size();
i++) {
493 if (hAndT[
i].
second < timeAtEntrance) {
494 timeAtEntrance = hAndT[
i].second;
501 std::sort(LC_indices.begin(), LC_indices.end(), [&MtdSimLayerClusters](
int i,
int j) {
502 return (*MtdSimLayerClusters)[
i].simLCTime() < (*MtdSimLayerClusters)[
j].simLCTime();
518 <<
"\n CP charge " << sc.charge() <<
"\n CP pdgId " << sc.pdgId()
519 <<
"\n CP energy " << sc.energy() <<
" GeV\n CP eta " << sc.eta()
520 <<
"\n CP phi " << sc.phi()
521 <<
"\n number of cells = " << sc.hits_and_fractions().size() << std::endl;
522 for (
unsigned int i = 0;
i < sc.hits_and_fractions().size(); ++
i) {
523 DetId id(sc.detIds_and_rows()[
i].first);
525 <<
std::fixed << std::setprecision(3) <<
" hit " << sc.detIds_and_rows()[
i].first <<
" on layer " 526 <<
geomTools_.
layer(
id) <<
" at time " << sc.hits_and_times()[
i].second <<
" ns" << std::endl;
529 <<
" ns \n Cluster pos" << sc.simLCPos() <<
" cm\n" 530 <<
std::fixed << std::setprecision(6) <<
" Cluster energy " 531 <<
convertUnitsTo(0.001_MeV, sc.simLCEnergy()) <<
" MeV" << std::endl;
539 <<
"\n CP charge " << sc.charge() <<
"\n CP pdgId " << sc.pdgId()
540 <<
"\n CP energy " << sc.energy() <<
" GeV\n CP eta " << sc.eta()
541 <<
"\n CP phi " << sc.phi()
542 <<
"\n number of layer clusters = " << sc.numberOfClusters()
543 <<
"\n time of first simhit " << sc.time() <<
" ns\n position of first simhit" 544 << sc.position() <<
"cm" << std::endl;
546 for (
const auto &lc : sc.clusters())
561 cp.addSimCluster(ref);
585 std::vector<std::pair<uint64_t, const PSimHit *>> simHitPointers;
586 std::unordered_map<int, std::map<uint64_t, float>> simTrackDetIdEnergyMap;
587 std::unordered_map<int, std::map<uint64_t, float>> simTrackDetIdTimeMap;
592 for (
unsigned int i = 0;
i < simHitPointers.size(); ++
i) {
598 std::unordered_map<int, int> trackid_to_track_index;
599 std::unordered_map<uint32_t, float> vertex_time_map;
610 trackid_to_track_index[
t.trackId()] =
idx;
641 std::vector<int> used_sim_tracks(
tracks.size(), 0);
642 std::vector<int> collapsed_vertices(
vertices.size(), 0);
646 if (
v.parentIndex() != -1) {
647 auto const trk_idx = trackid_to_track_index[
v.parentIndex()];
648 auto origin_vtx =
tracks[trk_idx].vertIndex();
649 if (used_sim_tracks[trk_idx]) {
653 collapsed_vertices[
v.vertexId()] = used_sim_tracks[trk_idx];
657 if (collapsed_vertices[origin_vtx])
658 origin_vtx = collapsed_vertices[origin_vtx];
663 used_sim_tracks[trk_idx] =
v.vertexId();
667 auto const &vertexMothersProp =
get(vertex_name,
decay);
671 for (
size_t i = 0;
i <
tracks.size(); ++
i) {
672 if (!used_sim_tracks[
i]) {
673 auto origin_vtx =
tracks[
i].vertIndex();
675 if (collapsed_vertices[origin_vtx])
676 origin_vtx = collapsed_vertices[origin_vtx];
687 if (
v.parentIndex() != -1) {
689 if (collapsed_vertices[
v.vertexId()])
694 SimHitsAccumulator_dfs_visitor
vis;
695 depth_first_search(
decay, visitor(
vis));
696 CaloParticle_dfs_visitor caloParticleCreator(
700 simTrackDetIdEnergyMap,
701 simTrackDetIdTimeMap,
712 depth_first_search(
decay, visitor(caloParticleCreator));
717 make_label_writer(make_transform_value_property_map(&graphviz_vertex,
get(vertex_name,
decay))),
718 make_label_writer(make_transform_value_property_map(&graphviz_edge,
get(edge_weight,
decay))));
724 std::unordered_map<
int, std::map<uint64_t, float>> &simTrackDetIdEnergyMap,
725 std::unordered_map<
int, std::map<uint64_t, float>> &simTrackDetIdTimeMap,
732 event.getByLabel(collectionTag, hSimHits);
734 for (
auto const &
simHit : *hSimHits) {
743 if (
id ==
DetId(0)) {
748 if (
simHit.trackId() == 0) {
752 returnValue.emplace_back(
id, &
simHit);
762 uniqueId |=
pixel.first << 16;
763 uniqueId |=
pixel.second;
765 simTrackDetIdEnergyMap[
simHit.trackId()][uniqueId] +=
simHit.energyLoss();
768 if (simTrackDetIdTimeMap[
simHit.trackId()][uniqueId] == 0. ||
769 simHit.tof() < simTrackDetIdTimeMap[
simHit.trackId()][uniqueId]) {
770 simTrackDetIdTimeMap[
simHit.trackId()][uniqueId] =
simHit.tof();
775 <<
"hitId " <<
id.rawId() <<
" from track " <<
simHit.trackId() <<
" in layer " <<
geomTools_.
layer(
id)
void initializeEvent(const edm::Event &event, const edm::EventSetup &setup) override
std::vector< MtdSimLayerCluster > MtdSimLayerClusterCollection
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
const edm::ESGetToken< MTDTopology, MTDTopologyRcd > mtdtopoToken_
const edm::InputTag simVertexLabel_
GlobalPoint globalPosition(const DetId &id, const LocalPoint &local_point) const
std::vector< MtdCaloParticle > MtdCaloParticleCollection
ProductRegistryHelper::BranchAliasSetterT< ProductType > produces()
MtdTruthAccumulator(const edm::ParameterSet &config, edm::ProducesCollector, edm::ConsumesCollector &iC)
std::pair< float, float > pixelInModule(const DetId &id, const int row, const int column) const
edm::InputTag genParticleLabel_
std::unique_ptr< MtdCaloParticleCollection > pCaloParticles
const edm::InputTag simTrackLabel_
const edm::ESGetToken< MTDGeometry, MTDDigiGeometryRecord > geomToken_
const std::string messageCategory_
const unsigned int maximumSubsequentBunchCrossing_
const MTDTopology * topology
void fillSimHits(std::vector< std::pair< uint64_t, const PSimHit *>> &returnValue, std::unordered_map< int, std::map< uint64_t, float >> &simTrackDetIdEnergyMap, std::unordered_map< int, std::map< uint64_t, float >> &simTrackDetIdTimeMap, const T &event, const edm::EventSetup &setup)
Fills the supplied vector with pointers to the SimHits, checking for bad modules if required...
std::unique_ptr< MtdSimTracksterCollection > pMtdSimTracksters
void accumulateEvent(const T &event, const edm::EventSetup &setup, const edm::Handle< edm::HepMCProduct > &hepMCproduct)
Both forms of accumulate() delegate to this templated method.
const unsigned int bunchSpacing_
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
void setTopology(MTDTopology const *topo)
constexpr NumType convertUnitsTo(double desiredUnits, NumType val)
void put(edm::Event &evt, double value, const char *instanceName)
const SimTrack * simTrack
U second(std::pair< T, U > const &p)
#define IfLogDebug(cond, cat)
std::unique_ptr< MtdSimLayerClusterCollection > pMtdSimLayerClusters
adjacency_list< listS, vecS, directedS, VertexMotherParticleProperty, EdgeParticleClustersProperty > DecayChain
unsigned int layer(const DetId &) const
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
std::unordered_multimap< Barcode_t, Index_t > m_simHitBarcodeToIndex
Abs< T >::type abs(const T &t)
OutputCollections output_
std::vector< uint32_t > sc_start_
std::pair< LocalPoint, GlobalPoint > position(const DetId &id, int row=0, int column=0) const
std::unique_ptr< MtdSimClusterCollection > pSimClusters
Functor that operates on <T>
void setGeometry(MTDGeometry const *geom)
calo_particles m_caloParticles
const unsigned int maximumPreviousBunchCrossing_
std::vector< uint32_t > sc_stop_
Log< level::Info, false > LogInfo
constexpr NumType convertMmToCm(NumType millimeters)
unsigned long long uint64_t
bool isETL(const DetId &) const
const double maxPseudoRapidity_
edm::Handle< std::vector< SimVertex > > hSimVertices
std::vector< edm::InputTag > collectionTags_
std::unordered_map< uint64_t, float > m_detIdToTotalSimEnergy
#define DEFINE_DIGI_ACCUMULATOR(type)
static int position[264][3]
void accumulate(const edm::Event &event, const edm::EventSetup &setup) override
void swap(calo_particles &oth)
std::vector< MtdSimCluster > MtdSimClusterCollection
int module(const DetId &) const
edm::Handle< std::vector< SimTrack > > hSimTracks
Log< level::Warning, false > LogWarning
void finalizeEvent(edm::Event &event, const edm::EventSetup &setup) override
static std::string const source
mtd::MTDGeomUtil geomTools_
std::vector< MtdSimTrackster > MtdSimTracksterCollection
edm::InputTag hepMCproductLabel_
Needed to add HepMC::GenVertex to SimVertex.