5 #define PRINT_DEBUG true 8 #pragma GCC diagnostic pop 17 #include <unordered_map> 62 using Index_t = unsigned;
63 using Barcode_t =
int;
64 const std::string messageCategoryGraph_(
"MtdTruthAccumulatorGraphProducer");
87 std::unordered_map<
int,
std::map<
uint64_t, std::tuple<float, float, LocalPoint>>> &simTrackDetIdMap,
164 class CaloParticle_dfs_visitor :
public boost::default_dfs_visitor {
166 CaloParticle_dfs_visitor(
169 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex,
170 std::unordered_map<
int,
std::map<
uint64_t, std::tuple<float, float, LocalPoint>>> &simTrackDetIdMap,
171 std::unordered_map<uint32_t, float> &vertex_time_map,
175 simHitBarcodeToIndex_(simHitBarcodeToIndex),
176 simTrackDetIdMap_(simTrackDetIdMap),
177 vertex_time_map_(vertex_time_map),
179 template <
typename Vertex,
typename Graph>
185 auto const vertex_property =
get(vertex_name,
g, u);
186 if (!vertex_property.simTrack)
190 auto trackIdx = vertex_property.simTrack->trackId();
193 <<
" Found " << simHitBarcodeToIndex_.count(trackIdx) <<
" associated simHits" << std::endl;
194 if (simHitBarcodeToIndex_.count(trackIdx)) {
195 output_.pSimClusters->emplace_back(*vertex_property.simTrack);
196 auto &simcluster = output_.pSimClusters->back();
197 std::unordered_map<uint64_t, float> acc_energy;
198 for (
auto const &hit_and_energy : simTrackDetIdMap_[trackIdx]) {
199 acc_energy[hit_and_energy.first] += std::get<0>(hit_and_energy.second);
201 for (
auto const &hit_and_energy : acc_energy) {
202 simcluster.addHitAndFraction(hit_and_energy.first, hit_and_energy.second);
203 simcluster.addHitEnergy(hit_and_energy.second);
204 simcluster.addHitTime(std::get<1>(
205 simTrackDetIdMap_[simcluster.g4Tracks()[0].trackId() +
207 simcluster.addHitPosition(std::get<2>(
208 simTrackDetIdMap_[simcluster.g4Tracks()[0].trackId() +
210 simcluster.setTrackIdOffset(
offset);
216 template <
typename Edge,
typename Graph>
217 void examine_edge(Edge
e,
const Graph &
g) {
219 auto vertex_property =
get(vertex_name,
g,
src);
220 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
221 auto edge_property =
get(edge_weight,
g,
e);
222 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
"Considering CaloParticle: " << edge_property.simTrack->trackId();
223 if (selector_(edge_property)) {
224 IfLogDebug(
DEBUG, messageCategoryGraph_) <<
"Adding CaloParticle: " << edge_property.simTrack->trackId();
225 output_.pCaloParticles->emplace_back(*(edge_property.simTrack));
226 output_.pCaloParticles->back().addSimTime(vertex_time_map_[(edge_property.simTrack)->vertIndex()]);
227 caloParticles_.sc_start_.push_back(output_.pSimClusters->size());
232 template <
typename Edge,
typename Graph>
233 void finish_edge(Edge
e,
const Graph &
g) {
235 auto vertex_property =
get(vertex_name,
g,
src);
236 if (
src == 0
or (vertex_property.simTrack ==
nullptr)) {
237 auto edge_property =
get(edge_weight,
g,
e);
238 if (selector_(edge_property)) {
239 caloParticles_.sc_stop_.push_back(output_.pSimClusters->size());
247 std::unordered_multimap<Barcode_t, Index_t> &simHitBarcodeToIndex_;
248 std::unordered_map<int, std::map<uint64_t, std::tuple<float, float, LocalPoint>>> &simTrackDetIdMap_;
249 std::unordered_map<uint32_t, float> &vertex_time_map_;
257 : messageCategory_(
"MtdTruthAccumulator"),
258 maximumPreviousBunchCrossing_(
config.getParameter<unsigned
int>(
"maximumPreviousBunchCrossing")),
259 maximumSubsequentBunchCrossing_(
config.getParameter<unsigned
int>(
"maximumSubsequentBunchCrossing")),
260 bunchSpacing_(
config.getParameter<unsigned
int>(
"bunchspace")),
268 minEnergy_(
config.getParameter<double>(
"MinEnergy")),
269 maxPseudoRapidity_(
config.getParameter<double>(
"MaxPseudoRapidity")),
270 premixStage1_(
config.getParameter<
bool>(
"premixStage1")) {
279 std::vector<std::string> parameterNames = simHitCollectionConfig.getParameterNames();
281 for (
auto const ¶meterName : parameterNames) {
282 std::vector<edm::InputTag>
tags = simHitCollectionConfig.getParameter<std::vector<edm::InputTag>>(parameterName);
287 iC.
consumes<std::vector<PSimHit>>(collectionTag);
288 isEtl_ = (collectionTag.instance().find(
"FastTimerHitsEndcap") != std::string::npos);
296 producesCollector.
produces<std::vector<std::pair<uint64_t, float>>>(
"MergedMtdTruth");
310 geom = geometryHandle.product();
313 topology = topologyHandle.product();
342 <<
event.bunchCrossing();
361 auto totalEnergies = std::make_unique<std::vector<std::pair<uint64_t, float>>>();
364 std::sort(totalEnergies->begin(), totalEnergies->end());
365 event.put(
std::move(totalEnergies),
"MergedMtdTruth");
368 auto hitsAndEnergies = sc.hits_and_fractions();
369 sc.clearHitsAndFractions();
370 sc.clearHitsEnergy();
371 for (
auto &hAndE : hitsAndEnergies) {
375 fraction = hAndE.second / totalenergy;
378 <<
"TotalSimEnergy for hit " << hAndE.first <<
" is 0! The fraction for this hit cannot be computed.";
379 sc.addHitAndFraction(hAndE.first,
fraction);
380 sc.addHitEnergy(hAndE.second);
389 <<
"\n charge " << sc.charge() <<
"\n pdgId " << sc.pdgId() <<
"\n energy " 390 << sc.energy() <<
" GeV\n eta " << sc.eta() <<
"\n phi " << sc.phi()
391 <<
"\n number of cells = " << sc.hits_and_fractions().size() << std::endl;
392 for (
unsigned int i = 0;
i < sc.hits_and_fractions().size(); ++
i) {
393 DetId id(sc.detIds_and_rows()[
i].first);
397 <<
" col " << (
unsigned int)(sc.detIds_and_rows()[
i].second).
second <<
" at time " 398 << sc.hits_and_times()[
i].second <<
" ns" << std::endl;
412 uint32_t SC_index = 0;
413 uint32_t LC_index = 0;
414 for (
const auto &sc : *scHandle) {
415 auto const &hAndF = sc.hits_and_fractions();
416 auto const &hAndE = sc.hits_and_energies();
417 auto const &hAndT = sc.hits_and_times();
418 auto const &hAndP = sc.hits_and_positions();
419 auto const &hAndR = sc.detIds_and_rows();
421 std::vector<int>
indices(hAndF.size());
430 std::vector<uint32_t> LC_indices;
435 float SimLCenergy = 0.;
436 float SimLCx = 0., SimLCy = 0., SimLCz = 0.;
438 auto push_back_hit = [&](
const int &ind) {
439 tmpLC.addHitAndFraction(hAndF[ind].
first, hAndF[ind].
second);
440 tmpLC.addHitEnergy(hAndE[ind].
second);
441 tmpLC.addHitTime(hAndT[ind].
second);
442 tmpLC.addHitPosition(hAndP[ind].
second);
445 auto update_clu_info = [&](
const int &ind) {
446 double energy = hAndE[ind].second;
463 auto push_back_clu = [&](
const uint32_t &SC_index, uint32_t &LC_index) {
464 tmpLC.addCluEnergy(SimLCenergy);
465 LocalPoint SimLCpos(SimLCx / SimLCenergy, SimLCy / SimLCenergy, SimLCz / SimLCenergy);
466 tmpLC.addCluLocalPos(SimLCpos);
471 tmpLC.addCluIndex(SC_index);
472 tmpLC.computeClusterTime();
473 tmpLC.setTrackIdOffset(sc.trackIdOffset());
475 LC_indices.push_back(LC_index);
482 update_clu_info(prev);
483 for (
const auto &ind :
indices) {
495 push_back_clu(SC_index, LC_index);
499 update_clu_info(ind);
505 push_back_clu(SC_index, LC_index);
510 float timeAtEntrance = 99.;
511 uint32_t idAtEntrance = 0;
512 for (uint32_t
i = 0;
i < (uint32_t)hAndT.size();
i++) {
513 if (hAndT[
i].
second < timeAtEntrance) {
514 timeAtEntrance = hAndT[
i].second;
521 std::sort(LC_indices.begin(), LC_indices.end(), [&MtdSimLayerClusters](
int i,
int j) {
522 return (*MtdSimLayerClusters)[
i].simLCTime() < (*MtdSimLayerClusters)[
j].simLCTime();
538 <<
"\n CP charge " << sc.charge() <<
"\n CP pdgId " << sc.pdgId()
539 <<
"\n CP energy " << sc.energy() <<
" GeV\n CP eta " << sc.eta()
540 <<
"\n CP phi " << sc.phi()
541 <<
"\n number of cells = " << sc.hits_and_fractions().size() << std::endl;
542 for (
unsigned int i = 0;
i < sc.hits_and_fractions().size(); ++
i) {
543 DetId id(sc.detIds_and_rows()[
i].first);
545 <<
std::fixed << std::setprecision(3) <<
" hit " << sc.detIds_and_rows()[
i].first <<
" on layer " 546 <<
geomTools_.
layer(
id) <<
" at time " << sc.hits_and_times()[
i].second <<
" ns" << std::endl;
549 <<
" ns \n Cluster pos" << sc.simLCPos() <<
" cm\n" 550 <<
std::fixed << std::setprecision(6) <<
" Cluster energy " 551 <<
convertUnitsTo(0.001_MeV, sc.simLCEnergy()) <<
" MeV" << std::endl;
559 <<
"\n CP charge " << sc.charge() <<
"\n CP pdgId " << sc.pdgId()
560 <<
"\n CP energy " << sc.energy() <<
" GeV\n CP eta " << sc.eta()
561 <<
"\n CP phi " << sc.phi()
562 <<
"\n number of layer clusters = " << sc.numberOfClusters()
563 <<
"\n time of first simhit " << sc.time() <<
" ns\n position of first simhit" 564 << sc.position() <<
"cm" << std::endl;
566 for (
const auto &lc : sc.clusters())
581 cp.addSimCluster(ref);
605 std::vector<std::pair<uint64_t, const PSimHit *>> simHitPointers;
606 std::unordered_map<int, std::map<uint64_t, std::tuple<float, float, LocalPoint>>> simTrackDetIdMap;
611 for (
unsigned int i = 0;
i < simHitPointers.size(); ++
i) {
617 std::unordered_map<int, int> trackid_to_track_index;
618 std::unordered_map<uint32_t, float> vertex_time_map;
622 vertex_time_map[
i] =
vertices[
i].position().t() * 1e9 +
event.bunchCrossing() *
static_cast<int>(
bunchSpacing_);
629 trackid_to_track_index[
t.trackId()] =
idx;
660 std::vector<int> used_sim_tracks(
tracks.size(), 0);
661 std::vector<int> collapsed_vertices(
vertices.size(), 0);
665 if (
v.parentIndex() != -1) {
666 auto const trk_idx = trackid_to_track_index[
v.parentIndex()];
667 auto origin_vtx =
tracks[trk_idx].vertIndex();
668 if (used_sim_tracks[trk_idx]) {
672 collapsed_vertices[
v.vertexId()] = used_sim_tracks[trk_idx];
676 if (collapsed_vertices[origin_vtx])
677 origin_vtx = collapsed_vertices[origin_vtx];
680 used_sim_tracks[trk_idx] =
v.vertexId();
684 auto const &vertexMothersProp =
get(vertex_name,
decay);
688 for (
size_t i = 0;
i <
tracks.size(); ++
i) {
689 if (!used_sim_tracks[
i]) {
690 auto origin_vtx =
tracks[
i].vertIndex();
692 if (collapsed_vertices[origin_vtx])
693 origin_vtx = collapsed_vertices[origin_vtx];
703 if (
v.parentIndex() != -1) {
705 if (collapsed_vertices[
v.vertexId()])
710 SimHitsAccumulator_dfs_visitor
vis;
711 depth_first_search(
decay, visitor(
vis));
712 CaloParticle_dfs_visitor caloParticleCreator(
727 depth_first_search(
decay, visitor(caloParticleCreator));
732 make_label_writer(make_transform_value_property_map(&graphviz_vertex,
get(vertex_name,
decay))),
733 make_label_writer(make_transform_value_property_map(&graphviz_edge,
get(edge_weight,
decay))));
739 std::vector<std::pair<uint64_t, const PSimHit *>> &returnValue,
740 std::unordered_map<
int,
std::map<
uint64_t, std::tuple<float, float, LocalPoint>>> &simTrackDetIdMap,
747 event.getByLabel(collectionTag, hSimHits);
749 for (
auto const &
simHit : *hSimHits) {
758 if (
id ==
DetId(0)) {
763 if (
simHit.trackId() == 0) {
767 returnValue.emplace_back(
id, &
simHit);
778 uniqueId |=
pixel.first << 16;
779 uniqueId |=
pixel.second;
781 std::get<0>(simTrackDetIdMap[
simHit.trackId()][uniqueId]) +=
simHit.energyLoss();
784 if (std::get<1>(simTrackDetIdMap[
simHit.trackId()][uniqueId]) == 0. ||
785 simHit.tof() < std::get<1>(simTrackDetIdMap[
simHit.trackId()][uniqueId])) {
786 std::get<1>(simTrackDetIdMap[
simHit.trackId()][uniqueId]) =
simHit.tof();
789 float xSim = std::get<2>(simTrackDetIdMap[
simHit.trackId()][uniqueId]).
x() + simscaled.
x() *
simHit.energyLoss();
790 float ySim = std::get<2>(simTrackDetIdMap[
simHit.trackId()][uniqueId]).
y() + simscaled.
y() *
simHit.energyLoss();
791 float zSim = std::get<2>(simTrackDetIdMap[
simHit.trackId()][uniqueId]).
z() + simscaled.
z() *
simHit.energyLoss();
793 std::get<2>(simTrackDetIdMap[
simHit.trackId()][uniqueId]) = posSim;
797 <<
"hitId " <<
id.rawId() <<
" from track " <<
simHit.trackId() <<
" in layer " <<
geomTools_.
layer(
id)
807 for (
auto &tkIt : simTrackDetIdMap) {
808 for (
auto &uIt : tkIt.second) {
809 float accEnergy = std::get<0>(uIt.second);
810 float xSim = std::get<2>(uIt.second).
x() / accEnergy;
811 float ySim = std::get<2>(uIt.second).
y() / accEnergy;
812 float zSim = std::get<2>(uIt.second).
z() / accEnergy;
814 std::get<2>(uIt.second) = posSim;
void initializeEvent(const edm::Event &event, const edm::EventSetup &setup) override
std::vector< MtdSimLayerCluster > MtdSimLayerClusterCollection
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
int getMTDTopologyMode() const
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
virtual const Topology & topology() const
virtual const PixelTopology & specificTopology() 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
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.
LocalPoint pixelToModuleLocalPoint(const LocalPoint &plp, int row, int col) const
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
bool isBTL(const DetId &) const
static constexpr unsigned int k_tidOffset
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
const MTDGeomDet * idToDet(DetId) const override
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_
void fillSimHits(std::vector< std::pair< uint64_t, const PSimHit *>> &returnValue, std::unordered_map< int, std::map< uint64_t, std::tuple< float, float, LocalPoint >>> &simTrackDetIdMap, const T &event, const edm::EventSetup &setup)
Fills the supplied vector with pointers to the SimHits, checking for bad modules if required...
std::unordered_map< uint64_t, float > m_detIdToTotalSimEnergy
#define DEFINE_DIGI_ACCUMULATOR(type)
static int position[264][3]
Detector identifier class for the Barrel Timing Layer. The crystal count must start from 0...
void accumulate(const edm::Event &event, const edm::EventSetup &setup) override
void swap(calo_particles &oth)
std::vector< MtdSimCluster > MtdSimClusterCollection
BTLDetId::CrysLayout crysLayoutFromTopoMode(const int &topoMode)
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.