LDMX Software
dqm::PhotoNuclearDQM Class Reference

Public Member Functions

 PhotoNuclearDQM (const std::string &name, framework::Process &process)
 Constructor.
 
virtual ~PhotoNuclearDQM ()=default
 Destructor.
 
void configure (framework::config::Parameters &parameters) override
 Configure this analyzer using the user specified parameters.
 
void analyze (const framework::Event &event) override
 Process the event and create the histogram summaries.
 
void setHistLabels (const std::string &name, const std::vector< std::string > &labels)
 Helper function to label categorical histos.
 
void onProcessStart () override
 Method executed before processing of events begins.
 
constexpr bool isLightIon (const int pdgCode) const
 Check if the PDG code corresponds to a light ion.
 
- Public Member Functions inherited from framework::Analyzer
 Analyzer (const std::string &name, Process &process)
 Class constructor.
 
- Public Member Functions inherited from framework::EventProcessor
 EventProcessor (const std::string &name, Process &process)
 Class constructor.
 
virtual ~EventProcessor ()
 Class destructor.
 
virtual void onNewRun (const ldmx::RunHeader &runHeader)
 Callback for the EventProcessor to take any necessary action when the run being processed changes.
 
virtual void onFileOpen (EventFile &eventFile)
 Callback for the EventProcessor to take any necessary action when a new event input ROOT file is opened.
 
virtual void onFileClose (EventFile &eventFile)
 Callback for the EventProcessor to take any necessary action when a event input ROOT file is closed.
 
virtual void onProcessEnd ()
 Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.
 
template<class T >
const T & getCondition (const std::string &condition_name)
 Access a conditions object for the current event.
 
TDirectory * getHistoDirectory ()
 Access/create a directory in the histogram file for this event processor to create histograms and analysis tuples.
 
void setStorageHint (framework::StorageControl::Hint hint)
 Mark the current event as having the given storage control hint from this module.
 
void setStorageHint (framework::StorageControl::Hint hint, const std::string &purposeString)
 Mark the current event as having the given storage control hint from this module and the given purpose string.
 
int getLogFrequency () const
 Get the current logging frequency from the process.
 
int getRunNumber () const
 Get the run number from the process.
 
std::string getName () const
 Get the processor name.
 
void createHistograms (const std::vector< framework::config::Parameters > &histos)
 Internal function which is used to create histograms passed from the python configuration @parma histos vector of Parameters that configure histograms to create.
 

Public Attributes

bool count_light_ions_
 

Private Types

enum class  CompactEventType {
  single_neutron = 0 , single_charged_kaon = 1 , single_neutral_kaon = 2 , two_neutrons = 3 ,
  soft = 4 , other = 5
}
 
enum class  EventType {
  nothing_hard = 0 , single_neutron = 1 , two_neutrons = 2 , three_or_more_neutrons = 3 ,
  single_charged_pion = 4 , two_charged_pions = 5 , single_neutral_pion = 6 , single_charged_pion_and_nucleon = 7 ,
  single_charged_pion_and_two_nucleons = 8 , two_charged_pions_and_nucleon = 9 , single_neutral_pion_and_nucleon = 10 , single_neutral_pion_and_two_nucleons = 11 ,
  single_neutral_pion_charged_pion_and_nucleon = 12 , single_proton = 13 , two_protons = 14 , proton_neutron = 15 ,
  klong = 16 , charged_kaon = 17 , kshort = 18 , exotics = 19 ,
  multibody = 20
}
 

Private Member Functions

EventType classifyEvent (const std::vector< const ldmx::SimParticle * > daughters, double threshold)
 Method used to classify events.
 
CompactEventType classifyCompactEvent (const ldmx::SimParticle *pnGamma, const std::vector< const ldmx::SimParticle * > daughters, double threshold)
 Method used to classify events in a compact manner.
 
void findRecoilProperties (const ldmx::SimParticle *recoil)
 Fill the recoil electron-histograms.
 
std::vector< const ldmx::SimParticle * > findDaughters (const std::map< int, ldmx::SimParticle > &particleMap, const ldmx::SimParticle *parent) const
 Find all daughter particles of a parent.
 
void findParticleKinematics (const std::vector< const ldmx::SimParticle * > &pnDaughters)
 Fill histograms related to kinematics of PN products.
 
void findSubleadingKinematics (const ldmx::SimParticle *pnGamma, const std::vector< const ldmx::SimParticle * > &pnDaughters, const EventType eventType)
 Fill histograms related to the kinematics and subleading particles for 1n, kaon, and 2n type events.
 

Additional Inherited Members

- Static Public Member Functions inherited from framework::EventProcessor
static void declare (const std::string &classname, int classtype, EventProcessorMaker *)
 Internal function which is part of the PluginFactory machinery.
 
- Static Public Attributes inherited from framework::Analyzer
static const int CLASSTYPE {2}
 Constant used to track EventProcessor types by the PluginFactory.
 
- Protected Member Functions inherited from framework::EventProcessor
void abortEvent ()
 Abort the event immediately.
 
- Protected Attributes inherited from framework::EventProcessor
HistogramHelper histograms_
 Interface class for making and filling histograms.
 
NtupleManagerntuple_ {NtupleManager::getInstance()}
 Manager for any ntuples.
 
logging::logger theLog_
 The logger for this EventProcessor.
 

Detailed Description

Definition at line 22 of file PhotoNuclearDQM.h.

Member Enumeration Documentation

◆ CompactEventType

enum class dqm::PhotoNuclearDQM::CompactEventType
strongprivate

Definition at line 24 of file PhotoNuclearDQM.h.

24 {
25 single_neutron = 0,
26 single_charged_kaon = 1,
27 single_neutral_kaon = 2,
28 two_neutrons = 3,
29 soft = 4,
30 other = 5,
31 };

◆ EventType

enum class dqm::PhotoNuclearDQM::EventType
strongprivate

Definition at line 32 of file PhotoNuclearDQM.h.

32 {
33 nothing_hard = 0,
34 single_neutron = 1,
35 two_neutrons = 2,
36 three_or_more_neutrons = 3,
37 single_charged_pion = 4,
38 two_charged_pions = 5,
39 single_neutral_pion = 6,
40 single_charged_pion_and_nucleon = 7,
41 single_charged_pion_and_two_nucleons = 8,
42 two_charged_pions_and_nucleon = 9,
43 single_neutral_pion_and_nucleon = 10,
44 single_neutral_pion_and_two_nucleons = 11,
45 single_neutral_pion_charged_pion_and_nucleon = 12,
46 single_proton = 13,
47 two_protons = 14,
48 proton_neutron = 15,
49 klong = 16,
50 charged_kaon = 17,
51 kshort = 18,
52 exotics = 19,
53 multibody = 20,
54 };

Constructor & Destructor Documentation

◆ PhotoNuclearDQM()

dqm::PhotoNuclearDQM::PhotoNuclearDQM ( const std::string & name,
framework::Process & process )

Constructor.

Definition at line 6 of file PhotoNuclearDQM.cxx.

8 : framework::Analyzer(name, process) {}
Base class for a module which does not produce a data product.

Member Function Documentation

◆ analyze()

void dqm::PhotoNuclearDQM::analyze ( const framework::Event & event)
overridevirtual

Process the event and create the histogram summaries.

Parameters
eventThe event to analyze.

Implements framework::Analyzer.

Definition at line 224 of file PhotoNuclearDQM.cxx.

224 {
225 // Get the particle map from the event. If the particle map is empty,
226 // don't process the event.
227 auto particleMap{event.getMap<int, ldmx::SimParticle>("SimParticles")};
228 if (particleMap.size() == 0) {
229 return;
230 }
231
232 // Get the recoil electron
233 auto [trackID, recoil] = Analysis::getRecoil(particleMap);
234 findRecoilProperties(recoil);
235
236 // Use the recoil electron to retrieve the gamma that underwent a
237 // photo-nuclear reaction.
238 auto pnGamma{Analysis::getPNGamma(particleMap, recoil, 2500.)};
239 if (pnGamma == nullptr) {
240 ldmx_log(warn) << "PN Daughter is lost, skipping";
241 return;
242 }
243
244 const auto pnDaughters{findDaughters(particleMap, pnGamma)};
245
246 if (!pnDaughters.empty()) {
247 auto pn_vertex_volume{pnDaughters[0]->getVertexVolume()};
248 auto pn_interaction_material{pnDaughters[0]->getInteractionMaterial()};
249
250 // Let's start with the PN vertex volume
251 if (pn_vertex_volume.find("W_cooling") != std::string::npos) {
252 // W_cooling_volume_X
253 histograms_.fill("pn_vertex_volume", 2);
254 } else if (pn_vertex_volume.find("C_volume") != std::string::npos) {
255 // C_volume_X
256 histograms_.fill("pn_vertex_volume", 3);
257 } else if (pn_vertex_volume.find("PCB_volume") != std::string::npos) {
258 histograms_.fill("pn_vertex_volume", 4);
259 } else if (pn_vertex_volume.find("CarbonBasePlate") != std::string::npos) {
260 // CarbonBasePlate_volume
261 histograms_.fill("pn_vertex_volume", 5);
262 } else if (pn_vertex_volume.find("W_front") != std::string::npos) {
263 // W_front_volume_X
264 histograms_.fill("pn_vertex_volume", 6);
265 } else if (pn_vertex_volume.find("Si_volume") != std::string::npos) {
266 histograms_.fill("pn_vertex_volume", 7);
267 } else if (pn_vertex_volume.find("Glue") != std::string::npos) {
268 histograms_.fill("pn_vertex_volume", 8);
269 } else if (pn_vertex_volume.find("motherboard") != std::string::npos) {
270 histograms_.fill("pn_vertex_volume", 9);
271
272 } else {
273 ldmx_log(debug) << " Else pn_vertex_volume = " << pn_vertex_volume
274 << " with pn_interaction_material = "
275 << pn_interaction_material;
276 histograms_.fill("pn_vertex_volume", 1);
277 }
278
279 // Now the interaction material
280 if (pn_interaction_material.find("G4_Si") != std::string::npos) {
281 histograms_.fill("pn_interaction_material", 2);
282 } else if (pn_interaction_material.find("G4_W") != std::string::npos) {
283 histograms_.fill("pn_interaction_material", 3);
284 } else if (pn_interaction_material.find("FR4") != std::string::npos) {
285 // Glass epoxy
286 histograms_.fill("pn_interaction_material", 4);
287 } else if (pn_interaction_material.find("Steel") != std::string::npos) {
288 histograms_.fill("pn_interaction_material", 5);
289 } else if (pn_interaction_material.find("Epoxy") != std::string::npos) {
290 // CarbonEpoxyComposite
291 histograms_.fill("pn_interaction_material", 6);
292 } else if (pn_interaction_material.find("Scintillator") !=
293 std::string::npos) {
294 // This is the notion for PVT
295 histograms_.fill("pn_interaction_material", 7);
296 } else if (pn_interaction_material.find("Glue") != std::string::npos) {
297 // This is the notion for PVT
298 histograms_.fill("pn_interaction_material", 8);
299 } else if (pn_interaction_material.find("G4_AIR") != std::string::npos) {
300 // Air
301 histograms_.fill("pn_interaction_material", 9);
302 } else {
303 ldmx_log(debug) << " Else pn_interaction_material = "
304 << pn_interaction_material
305 << " with pn_vertex_volume = " << pn_vertex_volume;
306 histograms_.fill("pn_interaction_material", 1);
307 }
308 } else {
309 histograms_.fill("pn_vertex_volume", 0);
310 histograms_.fill("pn_interaction_material", 0);
311 }
312
313 findParticleKinematics(pnDaughters);
314
315 histograms_.fill("pn_particle_mult", pnGamma->getDaughters().size());
316 histograms_.fill("pn_gamma_energy", pnGamma->getEnergy());
317 histograms_.fill("pn_gamma_int_x", pnGamma->getEndPoint()[0]);
318 histograms_.fill("pn_gamma_int_y", pnGamma->getEndPoint()[1]);
319 histograms_.fill("pn_gamma_int_x:pn_gamma_int_y", pnGamma->getEndPoint()[0],
320 pnGamma->getEndPoint()[1]);
321 histograms_.fill("pn_gamma_int_z", pnGamma->getEndPoint()[2]);
322 histograms_.fill("pn_gamma_vertex_x", pnGamma->getVertex()[0]);
323 histograms_.fill("pn_gamma_vertex_y", pnGamma->getVertex()[1]);
324 histograms_.fill("pn_gamma_vertex_z", pnGamma->getVertex()[2]);
325
326 // Classify the event
327 auto eventType{classifyEvent(pnDaughters, 200)};
328 auto eventType500MeV{classifyEvent(pnDaughters, 500)};
329 auto eventType2000MeV{classifyEvent(pnDaughters, 2000)};
330
331 auto eventTypeComp{classifyCompactEvent(pnGamma, pnDaughters, 200)};
332 auto eventTypeComp500MeV{classifyCompactEvent(pnGamma, pnDaughters, 500)};
333 auto eventTypeComp2000MeV{classifyCompactEvent(pnGamma, pnDaughters, 2000)};
334
335 histograms_.fill("event_type", static_cast<int>(eventType));
336 histograms_.fill("event_type_500mev", static_cast<int>(eventType500MeV));
337 histograms_.fill("event_type_2000mev", static_cast<int>(eventType2000MeV));
338
339 histograms_.fill("event_type_compact", static_cast<int>(eventTypeComp));
340 histograms_.fill("event_type_compact_500mev",
341 static_cast<int>(eventTypeComp500MeV));
342 histograms_.fill("event_type_compact_2000mev",
343 static_cast<int>(eventTypeComp2000MeV));
344
345 switch (eventType) {
346 case EventType::single_neutron:
347 if (pnDaughters.size() > 1) {
348 auto secondHardestPdgID{abs(pnDaughters[1]->getPdgID())};
349 auto nEventType{-10};
350 if (secondHardestPdgID == 2112) {
351 nEventType = 0; // n + n
352 } else if (secondHardestPdgID == 2212) {
353 nEventType = 1; // p + n
354 } else if (secondHardestPdgID == 211) {
355 nEventType = 2; // Pi+/- + n
356 } else if (secondHardestPdgID == 111) {
357 nEventType = 3; // Pi0 + n
358 } else {
359 nEventType = 4; // other
360 }
361 histograms_.fill("1n_event_type", nEventType);
362 }
363 [[fallthrough]]; // Remaining code is important for 1n as well
364 case EventType::two_neutrons:
365 case EventType::charged_kaon:
366 case EventType::klong:
367 case EventType::kshort:
368 findSubleadingKinematics(pnGamma, pnDaughters, eventType);
369 break;
370 default: // Nothing to do
371 break;
372 }
373}
const ldmx::SimParticle * getPNGamma(const std::map< int, ldmx::SimParticle > &particleMap, const ldmx::SimParticle *recoil, const float &energyThreshold)
Get a pointer to the sim particle associated with the photon that underwent a photo-nuclear reaction.
std::tuple< int, const ldmx::SimParticle * > getRecoil(const std::map< int, ldmx::SimParticle > &particleMap)
Find and return the sim particle associated with the recoil electron.
void findSubleadingKinematics(const ldmx::SimParticle *pnGamma, const std::vector< const ldmx::SimParticle * > &pnDaughters, const EventType eventType)
Fill histograms related to the kinematics and subleading particles for 1n, kaon, and 2n type events.
std::vector< const ldmx::SimParticle * > findDaughters(const std::map< int, ldmx::SimParticle > &particleMap, const ldmx::SimParticle *parent) const
Find all daughter particles of a parent.
EventType classifyEvent(const std::vector< const ldmx::SimParticle * > daughters, double threshold)
Method used to classify events.
CompactEventType classifyCompactEvent(const ldmx::SimParticle *pnGamma, const std::vector< const ldmx::SimParticle * > daughters, double threshold)
Method used to classify events in a compact manner.
void findRecoilProperties(const ldmx::SimParticle *recoil)
Fill the recoil electron-histograms.
void findParticleKinematics(const std::vector< const ldmx::SimParticle * > &pnDaughters)
Fill histograms related to kinematics of PN products.
HistogramHelper histograms_
Interface class for making and filling histograms.
void fill(const std::string &name, const double &val)
Fill a 1D histogram.
Definition Histograms.h:166
Class representing a simulated particle.
Definition SimParticle.h:23

References classifyCompactEvent(), classifyEvent(), framework::HistogramHelper::fill(), findDaughters(), findParticleKinematics(), findRecoilProperties(), findSubleadingKinematics(), and framework::EventProcessor::histograms_.

◆ classifyCompactEvent()

PhotoNuclearDQM::CompactEventType dqm::PhotoNuclearDQM::classifyCompactEvent ( const ldmx::SimParticle * pnGamma,
const std::vector< const ldmx::SimParticle * > daughters,
double threshold )
private

Method used to classify events in a compact manner.

Definition at line 481 of file PhotoNuclearDQM.cxx.

483 {
484 short n{0}, n_t{0}, k0l{0}, kp{0}, k0s{0}, soft{0};
485
486 // Loop through all of the PN daughters and extract kinematic
487 // information.
488 for (const auto &daughter : daughters) {
489 // Calculate the kinetic energy
490 auto ke{daughter->getEnergy() - daughter->getMass()};
491
492 // Get the PDG ID
493 auto pdgID{abs(daughter->getPdgID())};
494
495 if (ke < 500) {
496 soft++;
497 continue;
498 }
499
500 if (ke >= 0.8 * pnGamma->getEnergy()) {
501 if (pdgID == 2112) {
502 n++;
503 } else if (pdgID == 130) {
504 k0l++;
505 } else if (pdgID == 321) {
506 kp++;
507 } else if (pdgID == 310) {
508 k0s++;
509 }
510 continue;
511 }
512
513 if ((pdgID == 2112) && ke > threshold) {
514 n_t++;
515 }
516 }
517
518 int neutral_kaons{k0l + k0s};
519
520 if (n != 0) {
521 return PhotoNuclearDQM::CompactEventType::single_neutron;
522 }
523 if (kp != 0) {
524 return PhotoNuclearDQM::CompactEventType::single_charged_kaon;
525 }
526 if (neutral_kaons != 0) {
527 return PhotoNuclearDQM::CompactEventType::single_neutral_kaon;
528 }
529 if (n_t == 2) {
530 return PhotoNuclearDQM::CompactEventType::two_neutrons;
531 }
532 if (soft == daughters.size()) {
533 return PhotoNuclearDQM::CompactEventType::soft;
534 }
535
536 return PhotoNuclearDQM::CompactEventType::other;
537}
double getEnergy() const
Get the energy of this particle [MeV].
Definition SimParticle.h:72

References ldmx::SimParticle::getEnergy().

Referenced by analyze().

◆ classifyEvent()

PhotoNuclearDQM::EventType dqm::PhotoNuclearDQM::classifyEvent ( const std::vector< const ldmx::SimParticle * > daughters,
double threshold )
private

Method used to classify events.

Note: Assumes that daughters is sorted by kinetic energy.

Definition at line 375 of file PhotoNuclearDQM.cxx.

376 {
377 short n{0}, p{0}, pi{0}, pi0{0}, exotic{0}, k0l{0}, kp{0}, k0s{0};
378
379 // Loop through all of the PN daughters and extract kinematic
380 // information.
381 for (const auto &daughter : daughters) {
382 // Calculate the kinetic energy
383 auto ke{daughter->getEnergy() - daughter->getMass()};
384
385 // Assuming the daughters are sorted by kinetic energy, if the kinetic
386 // energy is below threshold, we don't need to look at any further
387 // particles.
388 if (ke <= threshold) {
389 break;
390 }
391
392 // Get the PDG ID
393 auto pdgID{abs(daughter->getPdgID())};
394
395 if (pdgID == 2112) {
396 n++;
397 } else if (pdgID == 2212) {
398 p++;
399 } else if (pdgID == 211) {
400 pi++;
401 } else if (pdgID == 111) {
402 pi0++;
403 } else if (pdgID == 130) {
404 k0l++;
405 } else if (pdgID == 321) {
406 kp++;
407 } else if (pdgID == 310) {
408 k0s++;
409 } else {
410 exotic++;
411 }
412 }
413
414 int kaons = k0l + kp + k0s;
415 int nucleons = n + p;
416 int pions = pi + pi0;
417 int count = nucleons + pions + exotic + kaons;
418
419 if (count == 0) {
420 return EventType::nothing_hard;
421 }
422 if (count == 1) {
423 if (n == 1) {
424 return EventType::single_neutron;
425 } else if (p == 1) {
426 return EventType::single_proton;
427 } else if (pi0 == 1) {
428 return EventType::single_neutral_pion;
429 } else if (pi == 1) {
430 return EventType::single_charged_pion;
431 }
432 }
433 if (count == 2) {
434 if (n == 2) {
435 return EventType::two_neutrons;
436 } else if (n == 1 && p == 1) {
437 return EventType::proton_neutron;
438 } else if (p == 2) {
439 return EventType::two_protons;
440 } else if (pi == 2) {
441 return EventType::two_charged_pions;
442 } else if (pi == 1 && nucleons == 1) {
443 return EventType::single_charged_pion_and_nucleon;
444 } else if (pi0 == 1 && nucleons == 1) {
445 return EventType::single_neutral_pion_and_nucleon;
446 }
447 }
448
449 if (count == 3) {
450 if (pi == 1 && nucleons == 2) {
451 return EventType::single_charged_pion_and_two_nucleons;
452 } else if (pi == 2 && nucleons == 1) {
453 return EventType::two_charged_pions_and_nucleon;
454 } // else
455 else if (pi0 == 1 && nucleons == 2) {
456 return EventType::single_neutral_pion_and_two_nucleons;
457 } else if (pi0 == 1 && nucleons == 1 && pi == 1) {
458 return EventType::single_neutral_pion_charged_pion_and_nucleon;
459 }
460 }
461 if (count >= 3 && count == n) {
462 return EventType::three_or_more_neutrons;
463 }
464
465 if (kaons == 1) {
466 if (k0l == 1) {
467 return EventType::klong;
468 } else if (kp == 1) {
469 return EventType::charged_kaon;
470 } else if (k0s == 1) {
471 return EventType::kshort;
472 }
473 }
474 if (exotic == count && count != 0) {
475 return EventType::exotics;
476 }
477
478 return EventType::multibody;
479}

Referenced by analyze().

◆ configure()

void dqm::PhotoNuclearDQM::configure ( framework::config::Parameters & parameters)
overridevirtual

Configure this analyzer using the user specified parameters.

Parameters
parametersSet of parameters used to configure this analyzer.

Reimplemented from framework::EventProcessor.

Definition at line 220 of file PhotoNuclearDQM.cxx.

220 {
221 count_light_ions_ = parameters.getParameter<bool>("count_light_ions", true);
222}

◆ findDaughters()

std::vector< const ldmx::SimParticle * > dqm::PhotoNuclearDQM::findDaughters ( const std::map< int, ldmx::SimParticle > & particleMap,
const ldmx::SimParticle * parent ) const
private

Find all daughter particles of a parent.

Particles are included if they>

  • Are in the particle map,
  • Are not photons or nuclear fragment, and
  • Are not a light ion (Z < 4) if the count_light_ions_ parameter is set to false

The products are sorted by kinetic energy, in descending order.

Definition at line 10 of file PhotoNuclearDQM.cxx.

12 {
13 std::vector<const ldmx::SimParticle *> pnDaughters;
14 for (const auto &daughterTrackID : parent->getDaughters()) {
15 // skip daughters that weren't saved
16 if (particleMap.count(daughterTrackID) == 0) {
17 continue;
18 }
19
20 auto daughter{&(particleMap.at(daughterTrackID))};
21
22 // Get the PDG ID
23 auto pdgID{daughter->getPdgID()};
24
25 // Ignore photons and nuclei
26 if (pdgID == 22 ||
27 (pdgID > 10000 && (!count_light_ions_ || !isLightIon(pdgID)))) {
28 continue;
29 }
30 pnDaughters.push_back(daughter);
31 }
32
33 std::sort(pnDaughters.begin(), pnDaughters.end(),
34 [](const auto &lhs, const auto &rhs) {
35 double lhs_ke = lhs->getEnergy() - lhs->getMass();
36 double rhs_ke = rhs->getEnergy() - rhs->getMass();
37 return lhs_ke > rhs_ke;
38 });
39
40 return pnDaughters;
41}
constexpr bool isLightIon(const int pdgCode) const
Check if the PDG code corresponds to a light ion.
std::vector< int > getDaughters() const
Get a vector containing the track IDs of all daughter particles.

References ldmx::SimParticle::getDaughters(), and isLightIon().

Referenced by analyze().

◆ findParticleKinematics()

void dqm::PhotoNuclearDQM::findParticleKinematics ( const std::vector< const ldmx::SimParticle * > & pnDaughters)
private

Fill histograms related to kinematics of PN products.

Definition at line 49 of file PhotoNuclearDQM.cxx.

50 {
51 double hardest_ke{-1}, hardest_theta{-1};
52 double hardest_proton_ke{-1}, hardest_proton_theta{-1};
53 double hardest_neutron_ke{-1}, hardest_neutron_theta{-1};
54 double hardest_pion_ke{-1}, hardest_pion_theta{-1};
55 double total_ke{0};
56 double total_neutron_ke{0};
57 int neutron_multiplicity{0};
58 // Loop through all of the PN daughters and extract kinematic
59 // information.
60 for (const auto *daughter : pnDaughters) {
61 // skip daughters that weren't saved
62
63 // Get the PDG ID
64 auto pdgID{daughter->getPdgID()};
65
66 // Calculate the kinetic energy
67 double ke{daughter->getEnergy() - daughter->getMass()};
68 total_ke += ke;
69
70 std::vector<double> vec{daughter->getMomentum()};
71 TVector3 pvec(vec[0], vec[1], vec[2]);
72
73 // Calculate the polar angle
74 auto theta{pvec.Theta() * (180 / 3.14159)};
75
76 if (hardest_ke < ke) {
77 hardest_ke = ke;
78 hardest_theta = theta;
79 }
80
81 if (pdgID == 2112) {
82 total_neutron_ke += ke;
83 neutron_multiplicity++;
84 if (hardest_neutron_ke < ke) {
85 hardest_neutron_ke = ke;
86 hardest_neutron_theta = theta;
87 }
88 }
89
90 if ((pdgID == 2212) && (hardest_proton_ke < ke)) {
91 hardest_proton_ke = ke;
92 hardest_proton_theta = theta;
93 }
94
95 if (((std::abs(pdgID) == 211) || (pdgID == 111)) &&
96 (hardest_pion_ke < ke)) {
97 hardest_pion_ke = ke;
98 hardest_pion_theta = theta;
99 }
100 }
101 histograms_.fill("hardest_ke", hardest_ke);
102 histograms_.fill("hardest_theta", hardest_theta);
103 histograms_.fill("h_ke_h_theta", hardest_ke, hardest_theta);
104 histograms_.fill("hardest_p_ke", hardest_proton_ke);
105 histograms_.fill("hardest_p_theta", hardest_proton_theta);
106 histograms_.fill("hardest_n_ke", hardest_neutron_ke);
107 histograms_.fill("hardest_n_theta", hardest_neutron_theta);
108 histograms_.fill("hardest_pi_ke", hardest_pion_ke);
109 histograms_.fill("hardest_pi_theta", hardest_pion_theta);
110
111 histograms_.fill("pn_neutron_mult", neutron_multiplicity);
112 histograms_.fill("pn_total_ke", total_ke);
113 histograms_.fill("pn_total_neutron_ke", total_neutron_ke);
114}

References framework::HistogramHelper::fill(), and framework::EventProcessor::histograms_.

Referenced by analyze().

◆ findRecoilProperties()

void dqm::PhotoNuclearDQM::findRecoilProperties ( const ldmx::SimParticle * recoil)
private

Fill the recoil electron-histograms.

Definition at line 42 of file PhotoNuclearDQM.cxx.

42 {
43 histograms_.fill("recoil_vertex_x", recoil->getVertex()[0]);
44 histograms_.fill("recoil_vertex_y", recoil->getVertex()[1]);
45 histograms_.fill("recoil_vertex_z", recoil->getVertex()[2]);
46 histograms_.fill("recoil_vertex_x:recoil_vertex_y", recoil->getVertex()[0],
47 recoil->getVertex()[1]);
48}
std::vector< double > getVertex() const
Get a vector containing the vertex of this particle in mm.

References framework::HistogramHelper::fill(), ldmx::SimParticle::getVertex(), and framework::EventProcessor::histograms_.

Referenced by analyze().

◆ findSubleadingKinematics()

void dqm::PhotoNuclearDQM::findSubleadingKinematics ( const ldmx::SimParticle * pnGamma,
const std::vector< const ldmx::SimParticle * > & pnDaughters,
const EventType eventType )
private

Fill histograms related to the kinematics and subleading particles for 1n, kaon, and 2n type events.

Note: This assumes that the daughter particles are sorted by energy.

Definition at line 116 of file PhotoNuclearDQM.cxx.

119 {
120 // Note: Assumes sorted by energy
121
122 double subleading_ke{-9999};
123 double nEnergy{-9999}, energyDiff{-9999}, energyFrac{-9999};
124
125 nEnergy = pnDaughters[0]->getEnergy() - pnDaughters[0]->getMass();
126 subleading_ke = -9999;
127 if (pnDaughters.size() > 1) {
128 subleading_ke = pnDaughters[1]->getEnergy() - pnDaughters[1]->getMass();
129 }
130 energyDiff = pnGamma->getEnergy() - nEnergy;
131 energyFrac = nEnergy / pnGamma->getEnergy();
132
133 if (eventType == EventType::single_neutron) {
134 histograms_.fill("1n_ke:2nd_h_ke", nEnergy, subleading_ke);
135 histograms_.fill("1n_neutron_energy", nEnergy);
136 histograms_.fill("1n_energy_diff", energyDiff);
137 histograms_.fill("1n_energy_frac", energyFrac);
138 } else if (eventType == EventType::two_neutrons) {
139 histograms_.fill("2n_n2_energy", subleading_ke);
140 auto energyFrac2n = (nEnergy + subleading_ke) / pnGamma->getEnergy();
141 histograms_.fill("2n_energy_frac", energyFrac2n);
142 histograms_.fill("2n_energy_other", pnGamma->getEnergy() - energyFrac2n);
143
144 } else if (eventType == EventType::charged_kaon) {
145 histograms_.fill("1kp_ke:2nd_h_ke", nEnergy, subleading_ke);
146 histograms_.fill("1kp_energy", nEnergy);
147 histograms_.fill("1kp_energy_diff", energyDiff);
148 histograms_.fill("1kp_energy_frac", energyFrac);
149 } else if (eventType == EventType::klong || eventType == EventType::kshort) {
150 histograms_.fill("1k0_ke:2nd_h_ke", nEnergy, subleading_ke);
151 histograms_.fill("1k0_energy", nEnergy);
152 histograms_.fill("1k0_energy_diff", energyDiff);
153 histograms_.fill("1k0_energy_frac", energyFrac);
154 }
155}

References framework::HistogramHelper::fill(), ldmx::SimParticle::getEnergy(), and framework::EventProcessor::histograms_.

Referenced by analyze().

◆ isLightIon()

bool dqm::PhotoNuclearDQM::isLightIon ( const int pdgCode) const
inlineconstexpr

Check if the PDG code corresponds to a light ion.

Nuclear PDG codes are given by ±10LZZZAAAI So to find the atomic number, we first divide by 10 (to lose the I-component) and then take the modulo with 1000.

TODO: Repeated code from SimCore, could probably live elsewhere.

Definition at line 149 of file PhotoNuclearDQM.h.

149 {
150 if (pdgCode > 1000000000) {
151 // Check if the atomic number is less than or equal to 4
152 return ((pdgCode / 10) % 1000) <= 4;
153 }
154 return false;
155 }

Referenced by findDaughters().

◆ onProcessStart()

void dqm::PhotoNuclearDQM::onProcessStart ( )
overridevirtual

Method executed before processing of events begins.

Reimplemented from framework::EventProcessor.

Definition at line 165 of file PhotoNuclearDQM.cxx.

165 {
166 std::vector<std::string> labels = {"",
167 "Nothing hard", // 0
168 "1 n", // 1
169 "2 n", // 2
170 "#geq 3 n", // 3
171 "1 #pi", // 4
172 "2 #pi", // 5
173 "1 #pi_{0}", // 6
174 "1 #pi A", // 7
175 "1 #pi 2 A", // 8
176 "2 #pi A", // 9
177 "1 #pi_{0} A", // 10
178 "1 #pi_{0} 2 A", // 11
179 "#pi_{0} #pi A", // 12
180 "1 p", // 13
181 "2 p", // 14
182 "pn", // 15
183 "K^{0}_{L} X", // 16
184 "K X", // 17
185 "K^{0}_{S} X", // 18
186 "exotics", // 19
187 "multi-body", // 20
188 ""};
189
190 setHistLabels("event_type", labels);
191 setHistLabels("event_type_500mev", labels);
192 setHistLabels("event_type_2000mev", labels);
193
194 labels = {"",
195 "1 n", // 0
196 "K#pm X", // 1
197 "1 K^{0}", // 2
198 "2 n", // 3
199 "Soft", // 4
200 "Other", // 5
201 ""};
202
203 setHistLabels("event_type_compact", labels);
204 setHistLabels("event_type_compact_500mev", labels);
205 setHistLabels("event_type_compact_2000mev", labels);
206
207 setHistLabels("1n_event_type", {"nn", "pn", "#pi^{+}n", "#pi^{0}n", "other"});
208
210 "pn_vertex_volume",
211 {"Didn't happen", "Else", "W Cooling", "C Cooling", "PCB",
212 "CarbonBasePlate", "Absorber", "Sensor", "Glue", "Motherboard"});
213
214 setHistLabels("pn_interaction_material",
215 {"Didn't happen", "Else", "Si", "W", "FR4", "Steel", "Epoxy",
216 "PVT", "Glue", "Air"});
217
218} // end of onProcessStart
void setHistLabels(const std::string &name, const std::vector< std::string > &labels)
Helper function to label categorical histos.

References setHistLabels().

◆ setHistLabels()

void dqm::PhotoNuclearDQM::setHistLabels ( const std::string & name,
const std::vector< std::string > & labels )

Helper function to label categorical histos.

Parameters
name: Name of the histo for the labels to set
labels: Labels on the X axis

Definition at line 157 of file PhotoNuclearDQM.cxx.

158 {
159 auto histo{histograms_.get(name)};
160 for (std::size_t ibin{1}; ibin <= labels.size(); ibin++) {
161 histo->GetXaxis()->SetBinLabel(ibin, labels[ibin - 1].c_str());
162 }
163}
TH1 * get(const std::string &name)
Get a pointer to a histogram by name.
Definition Histograms.h:194

References framework::HistogramHelper::get(), and framework::EventProcessor::histograms_.

Referenced by onProcessStart().

Member Data Documentation

◆ count_light_ions_

bool dqm::PhotoNuclearDQM::count_light_ions_

Definition at line 157 of file PhotoNuclearDQM.h.


The documentation for this class was generated from the following files: