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