LDMX Software
DigiDQM.cxx
1#include "Tracking/dqm/DigiDQM.h"
2
3#include <cmath>
4#include <map>
5#include <string>
6
8#include "Tracking/Event/FittedSiStripHit.h"
9#include "Tracking/Event/Measurement.h"
10#include "Tracking/Sim/TrackingUtils.h"
11
12namespace tracking::dqm {
13
15 sim_coll_name_ =
16 parameters.get<std::string>("sim_coll_name", "TaggerSimHits");
17 sim_pass_name_ = parameters.get<std::string>("sim_pass_name", "");
18 digi_coll_name_ = parameters.get<std::string>("digi_coll_name", "");
19 digi_pass_name_ = parameters.get<std::string>("digi_pass_name", "");
20 fitted_coll_name_ = parameters.get<std::string>("fitted_coll_name",
21 "TaggerFittedSiStripHits");
22 fitted_pass_name_ = parameters.get<std::string>("fitted_pass_name", "");
23 cluster_coll_name_ = parameters.get<std::string>("cluster_coll_name",
24 "TaggerClusterMeasurements");
25 cluster_pass_name_ = parameters.get<std::string>("cluster_pass_name", "");
26 n_sensors_ = parameters.get<int>("n_sensors", 14);
27}
28
30 // -------------------------------------------------------------------------
31 // Sim hits — one entry per hit
32 // -------------------------------------------------------------------------
33 if (event.exists(sim_coll_name_, sim_pass_name_)) {
34 const auto sim_hits = event.getCollection<ldmx::SimTrackerHit>(
35 sim_coll_name_, sim_pass_name_);
36
37 // Count per sensor for the multiplicity histograms
38 std::map<int, int> sim_count; // layer → count
39
40 for (const auto& hit : sim_hits) {
41 // getSensorID maps the G4 layer/module IDs to the same compact index
42 // that DigitizationProcessor stores in Measurement::layer_id_.
43 int layer =
44 ldmx::Measurement::layerIndex(tracking::sim::utils::getSensorID(hit));
45 if (layer < 0 || layer >= n_sensors_) continue;
46
47 const std::string s = std::to_string(layer);
48 histograms_.fill("sim_edep_s" + s, hit.getEdep());
49 sim_count[layer]++;
50 }
51
52 for (int i = 0; i < n_sensors_; ++i) {
53 histograms_.fill("sim_n_s" + std::to_string(i),
54 static_cast<double>(sim_count[i]));
55 }
56 }
57
58 // -------------------------------------------------------------------------
59 // Fitted strips (from StripFitProcessor)
60 // -------------------------------------------------------------------------
61 if (event.exists(fitted_coll_name_, fitted_pass_name_)) {
62 const auto fitted_hits = event.getCollection<ldmx::FittedSiStripHit>(
63 fitted_coll_name_, fitted_pass_name_);
64
65 std::map<int, int> strip_count;
66
67 for (const auto& hit : fitted_hits) {
68 // FittedSiStripHit::getLayerID() stores the same raw sensor index
69 // as Measurement::layer_id_ (set by getSensorID in
70 // DigitizationProcessor).
71 int layer = ldmx::Measurement::layerIndex(hit.getLayerID());
72 if (layer < 0 || layer >= n_sensors_) continue;
73
74 const std::string s = std::to_string(layer);
75 histograms_.fill("strip_amp_s" + s, hit.getAmplitude());
76 histograms_.fill("strip_t0_s" + s, hit.getT0());
77 if (hit.getNDF() > 0)
78 histograms_.fill("strip_chi2ndf_s" + s, hit.getChi2() / hit.getNDF());
79 strip_count[layer]++;
80 }
81
82 for (int i = 0; i < n_sensors_; ++i) {
83 histograms_.fill("strip_n_s" + std::to_string(i),
84 static_cast<double>(strip_count[i]));
85 }
86 }
87
88 // -------------------------------------------------------------------------
89 // Build truth_u lookup from digi Measurements (optional).
90 // layer → track_id → truth_u
91 // -------------------------------------------------------------------------
92 std::map<int, std::map<int, float>> truth_u_by_layer;
93 if (!digi_coll_name_.empty() &&
94 event.exists(digi_coll_name_, digi_pass_name_)) {
95 const auto digi_meas = event.getCollection<ldmx::Measurement>(
96 digi_coll_name_, digi_pass_name_);
97 for (const auto& m : digi_meas) {
98 int layer = m.getLayer();
99 if (layer < 0 || layer >= n_sensors_) continue;
100 if (std::isnan(m.getTruthU())) continue;
101 int tid =
102 m.getTrackIds().empty() ? -1 : static_cast<int>(m.getTrackIds()[0]);
103 truth_u_by_layer[layer][tid] = m.getTruthU();
104 }
105 }
106
107 // -------------------------------------------------------------------------
108 // Cluster measurements (from StripClusterProcessor)
109 // -------------------------------------------------------------------------
110 if (event.exists(cluster_coll_name_, cluster_pass_name_)) {
111 const auto cluster_meas = event.getCollection<ldmx::Measurement>(
112 cluster_coll_name_, cluster_pass_name_);
113
114 std::map<int, int> cluster_count;
115
116 for (const auto& meas : cluster_meas) {
117 int layer = meas.getLayer();
118 if (layer < 0 || layer >= n_sensors_) continue;
119
120 const std::string s = std::to_string(layer);
121 const float u = meas.getLocalPosition()[0];
122 histograms_.fill("cluster_u_s" + s, u);
123 histograms_.fill("cluster_amp_s" + s, meas.getClusterAmplitude());
124 histograms_.fill("cluster_time_s" + s, meas.getTime());
125 if (meas.getNStrips() > 0)
126 histograms_.fill("cluster_nstrips_s" + s, meas.getNStrips());
127 cluster_count[layer]++;
128
129 // sim_cluster_du: truth U (from digi Measurement) minus cluster U
130 int tid = meas.getTrackIds().empty()
131 ? -1
132 : static_cast<int>(meas.getTrackIds()[0]);
133 auto layer_it = truth_u_by_layer.find(layer);
134 if (layer_it != truth_u_by_layer.end()) {
135 auto tid_it = layer_it->second.find(tid);
136 if (tid_it != layer_it->second.end())
137 histograms_.fill("sim_cluster_du_s" + s, tid_it->second - u);
138 }
139 }
140
141 for (int i = 0; i < n_sensors_; ++i) {
142 histograms_.fill("cluster_n_s" + std::to_string(i),
143 static_cast<double>(cluster_count[i]));
144 }
145 }
146}
147
148} // namespace tracking::dqm
149
#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.
HistogramPool histograms_
helper object for making and filling histograms
Implements an event buffer system for storing event data.
Definition Event.h:40
bool exists(const std::string &name, const std::string &passName, bool unique=true) const
Check for the existence of an object or collection with the given name and pass name in the event.
Definition Event.cxx:107
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
Result of fitting a pulse shape to the ADC samples of a single readout strip.
static int layerIndex(int layer_id)
Internal layer index from a sensor ID (vol * 1000 + ly * 100 + sensor).
Represents a simulated tracker hit in the simulation.
DQM analyzer for silicon-strip digitization and clustering.
Definition DigiDQM.h:46
void analyze(const framework::Event &event) override
Process the event and make histograms or summaries.
Definition DigiDQM.cxx:29
void configure(framework::config::Parameters &parameters) override
Callback for the EventProcessor to configure itself from the given set of parameters.
Definition DigiDQM.cxx:14