27 if (!event.
exists(pn_collection_name_, pn_pass_name_)) {
33 const auto& pn_interactions =
42 int n_interactions = pn_interactions.size();
43 histograms_.fill(
"pn_interaction_count", n_interactions);
45 for (
const auto& interaction : pn_interactions) {
47 histograms_.fill(
"pn_target_z", interaction.getTargetZ());
48 histograms_.fill(
"pn_target_a", interaction.getTargetA());
49 histograms_.fill(
"pn_target_z:target_a", interaction.getTargetZ(),
50 interaction.getTargetA());
53 int n_cascade_secondaries = interaction.getNumImmediateSecondaries();
54 histograms_.fill(
"pn_cascade_multiplicity", n_cascade_secondaries);
59 auto descendant_map = interaction.getDescendantMap();
60 int total_descendants = 0;
61 for (
const auto& [secondary_id, descendants] : descendant_map) {
62 int n_desc = descendants.size();
63 total_descendants += n_desc;
66 histograms_.fill(
"pn_descendants_per_cascade_particle", n_desc);
68 histograms_.fill(
"pn_total_final_state_descendants", total_descendants);
76 if (total_descendants > 0) {
77 double compactness_ratio =
78 static_cast<double>(n_cascade_secondaries) / total_descendants;
79 histograms_.fill(
"pn_cascade_evolution_ratio", compactness_ratio);
88 sim_particles_coll_name_, sim_particles_passname_)};
89 if (particle_map.empty())
return;
92 auto [trackID, recoil] = analysis::getRecoil(particle_map);
93 findRecoilProperties(recoil);
97 auto pn_gamma{analysis::getPNGamma(particle_map, recoil, 2500.)};
98 if (pn_gamma ==
nullptr) {
99 ldmx_log(warn) <<
"PN Daughter is lost, skipping";
103 const auto pn_daughters{findDaughters(particle_map, pn_gamma)};
105 if (!pn_daughters.empty()) {
106 auto pn_vertex_volume{pn_daughters[0]->getVertexVolume()};
107 auto pn_interaction_material{pn_daughters[0]->getInteractionMaterial()};
110 if (pn_vertex_volume.find(
"W_cooling") != std::string::npos) {
112 histograms_.fill(
"pn_vertex_volume", 2);
113 }
else if (pn_vertex_volume.find(
"C_volume") != std::string::npos) {
115 histograms_.fill(
"pn_vertex_volume", 3);
116 }
else if (pn_vertex_volume.find(
"PCB_volume") != std::string::npos) {
117 histograms_.fill(
"pn_vertex_volume", 4);
118 }
else if (pn_vertex_volume.find(
"CarbonBasePlate") != std::string::npos) {
120 histograms_.fill(
"pn_vertex_volume", 5);
121 }
else if (pn_vertex_volume.find(
"W_front") != std::string::npos) {
123 histograms_.fill(
"pn_vertex_volume", 6);
124 }
else if (pn_vertex_volume.find(
"Si_volume") != std::string::npos) {
125 histograms_.fill(
"pn_vertex_volume", 7);
126 }
else if (pn_vertex_volume.find(
"Glue") != std::string::npos) {
127 histograms_.fill(
"pn_vertex_volume", 8);
128 }
else if (pn_vertex_volume.find(
"motherboard") != std::string::npos) {
129 histograms_.fill(
"pn_vertex_volume", 9);
131 ldmx_log(debug) <<
" Else pn_vertex_volume = " << pn_vertex_volume
132 <<
" with pn_interaction_material = "
133 << pn_interaction_material;
134 histograms_.fill(
"pn_vertex_volume", 1);
138 if (pn_interaction_material.find(
"Silicon") != std::string::npos ||
139 pn_interaction_material.find(
"G4_Si") != std::string::npos) {
140 histograms_.fill(
"pn_interaction_material", 2);
141 }
else if (pn_interaction_material.find(
"Tungsten") != std::string::npos ||
142 pn_interaction_material.find(
"G4_W") != std::string::npos) {
143 histograms_.fill(
"pn_interaction_material", 3);
144 }
else if (pn_interaction_material.find(
"FR4") != std::string::npos) {
146 histograms_.fill(
"pn_interaction_material", 4);
147 }
else if (pn_interaction_material.find(
"Steel") != std::string::npos) {
148 histograms_.fill(
"pn_interaction_material", 5);
149 }
else if (pn_interaction_material.find(
"Epoxy") != std::string::npos) {
151 histograms_.fill(
"pn_interaction_material", 6);
152 }
else if (pn_interaction_material.find(
"Scintillator") !=
155 histograms_.fill(
"pn_interaction_material", 7);
156 }
else if (pn_interaction_material.find(
"Glue") != std::string::npos) {
158 histograms_.fill(
"pn_interaction_material", 8);
159 }
else if (pn_interaction_material.find(
"Air") != std::string::npos ||
160 pn_interaction_material.find(
"G4_AIR") != std::string::npos) {
162 histograms_.fill(
"pn_interaction_material", 9);
164 ldmx_log(debug) <<
" Else pn_interaction_material = "
165 << pn_interaction_material
166 <<
" with pn_vertex_volume = " << pn_vertex_volume;
167 histograms_.fill(
"pn_interaction_material", 1);
170 histograms_.fill(
"pn_vertex_volume", 0);
171 histograms_.fill(
"pn_interaction_material", 0);
174 findParticleKinematics(pn_daughters,
"pn");
176 histograms_.fill(
"pn_particle_mult", pn_gamma->getDaughters().size());
177 histograms_.fill(
"pn_gamma_energy", pn_gamma->getEnergy());
178 histograms_.fill(
"pn_gamma_int_x", pn_gamma->getEndPoint()[0]);
179 histograms_.fill(
"pn_gamma_int_y", pn_gamma->getEndPoint()[1]);
180 histograms_.fill(
"pn_gamma_int_x:pn_gamma_int_y", pn_gamma->getEndPoint()[0],
181 pn_gamma->getEndPoint()[1]);
182 histograms_.fill(
"pn_gamma_int_z", pn_gamma->getEndPoint()[2]);
183 histograms_.fill(
"pn_gamma_vertex_x", pn_gamma->getVertex()[0]);
184 histograms_.fill(
"pn_gamma_vertex_y", pn_gamma->getVertex()[1]);
185 histograms_.fill(
"pn_gamma_vertex_z", pn_gamma->getVertex()[2]);
188 auto event_type{classifyEvent(pn_daughters, 200)};
189 auto event_type500_mev{classifyEvent(pn_daughters, 500)};
190 auto event_type2000_mev{classifyEvent(pn_daughters, 2000)};
192 auto event_type_comp{classifyCompactEvent(pn_gamma, pn_daughters, 200)};
193 auto event_type_comp500_mev{
194 classifyCompactEvent(pn_gamma, pn_daughters, 500)};
195 auto event_type_comp2000_mev{
196 classifyCompactEvent(pn_gamma, pn_daughters, 2000)};
198 histograms_.fill(
"event_type",
static_cast<int>(event_type));
199 histograms_.fill(
"event_type_500mev",
static_cast<int>(event_type500_mev));
200 histograms_.fill(
"event_type_2000mev",
static_cast<int>(event_type2000_mev));
201 histograms_.fill(
"event_type_compact",
static_cast<int>(event_type_comp));
202 histograms_.fill(
"event_type_compact_500mev",
203 static_cast<int>(event_type_comp500_mev));
204 histograms_.fill(
"event_type_compact_2000mev",
205 static_cast<int>(event_type_comp2000_mev));
207 switch (event_type) {
208 case EventType::single_neutron:
209 if (pn_daughters.size() > 1) {
210 auto second_hardest_pdg{std::abs(pn_daughters[1]->getPdgID())};
211 int n_event_type{-10};
212 if (second_hardest_pdg == 2112)
214 else if (second_hardest_pdg == 2212)
216 else if (second_hardest_pdg == 211)
218 else if (second_hardest_pdg == 111)
222 histograms_.fill(
"1n_event_type", n_event_type);
225 case EventType::two_neutrons:
226 case EventType::charged_kaon:
227 case EventType::klong:
228 case EventType::kshort:
229 findSubleadingKinematics(pn_gamma, pn_daughters, event_type);
236 analyzeInteractionDetails(event);
Class representing a simulated particle.
std::vector< double > getVertex() const
Get a vector containing the vertex of this particle in mm.