LDMX Software
SampleValidation.cxx
1#include "DQM/SampleValidation.h"
2
3#include "Math/Vector3D.h" // IWYU pragma: keep
4#include "SimCore/Event/SimParticle.h"
6
7namespace dqm {
8
10 target_scoring_plane_coll_name_ =
11 ps.get<std::string>("target_scoring_plane_coll_name");
12 target_scoring_plane_passname_ =
13 ps.get<std::string>("target_scoring_plane_passname");
14 sim_particles_coll_name_ = ps.get<std::string>("sim_particles_coll_name");
15 sim_particles_passname_ = ps.get<std::string>("sim_particles_passname");
16}
17
19 // Grab the SimParticle Map and Target Scoring Plane Hits
20 auto target_sp_hits(event.getCollection<ldmx::SimTrackerHit>(
21 target_scoring_plane_coll_name_, target_scoring_plane_passname_));
22 auto particle_map{event.getMap<int, ldmx::SimParticle>(
23 sim_particles_coll_name_, sim_particles_passname_)};
24
25 std::vector<int> primary_daughters;
26
27 double hard_thresh{9999.0};
28
29 // Loop over all SimParticles
30 for (auto const& it : particle_map) {
31 ldmx::SimParticle p = it.second;
32 std::vector<int> parents_track_ids = p.getParents();
33 std::vector<int> daughters = p.getDaughters();
34 const auto& pdgid = p.getPdgID();
35 const auto& vertex = p.getVertex();
36 const auto& energy = p.getEnergy();
37 const auto& momentum = p.getMomentum();
38 for (auto const& parent_track_id : parents_track_ids) {
39 if (parent_track_id == 0) {
40 ROOT::Math::XYZVector momentum_vec(momentum[0], momentum[1],
41 momentum[2]);
42 histograms_.fill("primaries_pdgid", pdgidLabel(pdgid));
43 histograms_.fill("primaries_energy", energy);
44 histograms_.fill("primaries_theta",
45 momentum_vec.Theta() * (180 / 3.14159));
46 histograms_.fill("primaries_pt", std::sqrt(momentum_vec.Perp2()));
47 hard_thresh = (2500. / 4000.) * energy;
48 primary_daughters = daughters;
49 for (const ldmx::SimTrackerHit& sphit : target_sp_hits) {
50 if (sphit.getTrackID() == it.first && sphit.getPosition()[2] < 0) {
51 histograms_.fill("beam_smear", vertex[0], vertex[1]);
52 }
53 }
54 }
55 } // end loop over parents
56 } // end loop over SimParticles (1st time)
57
58 std::vector<std::vector<int>> hardbrem_daughters;
59
60 for (auto const& it : particle_map) {
61 int trackid = it.first;
62 ldmx::SimParticle p = it.second;
63 const auto& momentum = p.getMomentum();
64 ROOT::Math::XYZVector momentum_vec(momentum[0], momentum[1], momentum[2]);
65 for (auto const& primary_daughter : primary_daughters) {
66 if (trackid == primary_daughter) {
67 histograms_.fill("primarydaughters_pdgid", pdgidLabel(p.getPdgID()));
68 if (p.getPdgID() == 22) {
69 histograms_.fill("daughterphoton_energy", p.getEnergy());
70 }
71 if (p.getEnergy() >= hard_thresh) {
72 histograms_.fill("harddaughters_pdgid", pdgidLabel(p.getPdgID()));
73 histograms_.fill("harddaughters_startZ", p.getVertex()[2]);
74 histograms_.fill("harddaughters_endZ", p.getEndPoint()[2]);
75 histograms_.fill("harddaughters_energy", p.getEnergy());
76 histograms_.fill("harddaughters_theta",
77 momentum_vec.Theta() * (180 / 3.14159));
78 histograms_.fill("harddaughters_pt", std::sqrt(momentum_vec.Perp2()));
79 hardbrem_daughters.push_back(p.getDaughters());
80 }
81 }
82 } // end loop over primary daughters
83 } // end loop over SimParticles (2nd time)
84
85 for (auto const& it : particle_map) {
86 int trackid = it.first;
87 ldmx::SimParticle p = it.second;
88 const auto& momentum = p.getMomentum();
89 ROOT::Math::XYZVector momentum_vec(momentum[0], momentum[1], momentum[2]);
90 for (const std::vector<int>& daughter_track_id : hardbrem_daughters) {
91 for (const int& daughter_id : daughter_track_id) {
92 if (trackid == daughter_id) {
93 histograms_.fill("hardbremdaughters_pdgid", pdgidLabel(p.getPdgID()));
94 histograms_.fill("hardbremdaughters_startZ", p.getVertex()[2]);
95 histograms_.fill("hardbremdaughters_endZ", p.getEndPoint()[2]);
96 histograms_.fill("hardbremdaughters_energy", p.getEnergy());
97 histograms_.fill("hardbremdaughters_theta",
98 momentum_vec.Theta() * (180 / 3.14159));
99 histograms_.fill("hardbremdaughters_pt",
100 std::sqrt(momentum_vec.Perp2()));
101 }
102 }
103 } // end loop over hardbrem daughters
104 } // end loop over SimParticles (3x time)
105
106 return;
107}
108
109float SampleValidation::pdgidLabel(const int pdgid) {
110 // initially assign label as "anything else"/overflow value,
111 // only change if the pdg id is something of interest
112 int label = 20;
113 if (pdgid == -11) label = 0; // e+
114 if (pdgid == 11) label = 1; // e-
115 if (pdgid == -13) label = 2; // μ+
116 if (pdgid == 13) label = 3; // μ-
117 if (pdgid == 22) label = 4; // γ
118 if (pdgid == 2212) label = 5; // proton
119 if (pdgid == 2112) label = 6; // neutron
120 if (pdgid == 211) label = 7; // π+
121 if (pdgid == -211) label = 8; // π-
122 if (pdgid == 111) label = 9; // π0
123 if (pdgid == 321) label = 10; // K+
124 if (pdgid == -321) label = 11; // K-
125 if (pdgid == 130) label = 12; // K-Long
126 if (pdgid == 310) label = 13; // K-Short
127 if (pdgid == 3122 || pdgid == 3222 || pdgid == 3212 || pdgid == 3112 ||
128 pdgid == 3322 || pdgid == 3312) {
129 label = 16; // strange baryons
130 }
131 /*
132 * Nuclear PDG codes are given by ±10LZZZAAAI so to find the atomic
133 * number, we divide by 10 (to lose I) and then take the modulo
134 * with 1000.
135 */
136 if (pdgid > 1000000000) { // nuclei
137 if (((pdgid / 10) % 1000) <= 4) {
138 label = 14; // light nuclei
139 } else {
140 label = 15; // heavy nuclei
141 }
142 }
143 // dark photon, need pdg id for other models like ALPs and SIMPs
144 if (pdgid == 622) label = 17;
145
146 if (pdgid == 17) label = 18; // fcp-
147 if (pdgid == -17) label = 19; // fcp+
148 if (label == 20) {
149 ldmx_log(debug) << "Unrecognized PDG ID: " << pdgid
150 << ", assigning to 'else'";
151 }
152
153 return label + 0.5;
154}
155
156} // namespace dqm
#define DECLARE_ANALYZER(CLASS)
Macro which allows the framework to construct an analyzer given its name during configuration.
Class which encapsulates information from a hit in a simulated tracking detector.
virtual void configure(framework::config::Parameters &ps) override
Callback for the EventProcessor to configure itself from the given set of parameters.
virtual void analyze(const framework::Event &event) override
Process the event and make histograms or summaries.
HistogramPool histograms_
helper object for making and filling histograms
Implements an event buffer system for storing event data.
Definition Event.h:40
const std::vector< ContentType > & getCollection(const std::string &collectionName, const std::string &passName) const
Get a collection (std::vector) of objects from the event bus.
Definition Event.h:409
void fill(const std::string &name, const T &val)
Fill a 1D histogram.
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:26
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75
Class representing a simulated particle.
Definition SimParticle.h:25
double getEnergy() const
Get the energy of this particle [MeV].
Definition SimParticle.h:74
std::vector< int > getParents() const
Get a vector containing the track IDs of the parent particles.
std::vector< double > getVertex() const
Get a vector containing the vertex of this particle in mm.
std::vector< int > getDaughters() const
Get a vector containing the track IDs of all daughter particles.
int getPdgID() const
Get the PDG ID of this particle.
Definition SimParticle.h:87
std::vector< double > getEndPoint() const
Get the end_point of this particle where it was destroyed or left the world volume [mm].
std::vector< double > getMomentum() const
Get a vector containing the momentum of this particle [MeV].
Represents a simulated tracker hit in the simulation.