LDMX Software
tracking::dqm::TrackingRecoDQM Class Reference

Public Member Functions

 TrackingRecoDQM (const std::string &name, framework::Process &process)
 
 ~TrackingRecoDQM ()=default
 Destructor.
 
void analyze (const framework::Event &event) override
 Process the event and make histograms or summaries.
 
void trackMonitoring (const std::vector< ldmx::Track > &tracks, const std::vector< ldmx::Measurement > &measurements, const std::string title, const bool &doDetail, const bool &doTruth)
 
void efficiencyPlots (const std::vector< ldmx::Track > &tracks, const std::vector< ldmx::Measurement > &measurements, const std::string &title)
 
void trackStateMonitoring (const std::vector< ldmx::Track > &tracks, ldmx::TrackStateType ts_type, const std::string &ts_title)
 Monitoring plots for tracks extrapolated to the ECAL Scoring plane.
 
void configure (framework::config::Parameters &parameters) override
 Configure the analyzer using the given user specified parameters.
 
void onProcessEnd () override
 Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.
 
void sortTracks (const std::vector< ldmx::Track > &tracks, std::vector< ldmx::Track > &uniqueTracks, std::vector< ldmx::Track > &duplicateTracks, std::vector< ldmx::Track > &fakeTracks)
 
- Public Member Functions inherited from framework::Analyzer
 Analyzer (const std::string &name, Process &process)
 Class constructor.
 
virtual void process (Event &event) final
 Processing an event for an Analyzer is calling analyze.
 
virtual void beforeNewRun (ldmx::RunHeader &run_header) final
 Don't allow Analyzers to add parameters to the run header.
 
- Public Member Functions inherited from framework::EventProcessor
 DECLARE_FACTORY (EventProcessor, EventProcessor *, const std::string &, Process &)
 declare that we have a factory for this class
 
 EventProcessor (const std::string &name, Process &process)
 Class constructor.
 
virtual ~EventProcessor ()=default
 Class destructor.
 
virtual void onNewRun (const ldmx::RunHeader &run_header)
 Callback for the EventProcessor to take any necessary action when the run being processed changes.
 
virtual void onFileOpen (EventFile &event_file)
 Callback for the EventProcessor to take any necessary action when a new event input ROOT file is opened.
 
virtual void onFileClose (EventFile &event_file)
 Callback for the EventProcessor to take any necessary action when a event input ROOT file is closed.
 
virtual void onProcessStart ()
 Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.
 
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.
 

Private Attributes

std::string track_collection_
 
std::string truth_collection_
 
std::string measurement_collection_
 
std::string measurement_passname_
 
std::string ecal_sp_coll_name_
 
std::string ecal_sp_passname_
 
std::string target_sp_coll_name_
 
std::string target_sp_passname_
 
std::string track_collection_events_passname_
 
std::string track_passname_
 
std::string truth_events_passname_
 
std::string truth_passname_
 
std::string title_ {"tagger_trk_"}
 
double track_prob_cut_ {0.5}
 
std::string subdetector_ {"Tagger"}
 
bool do_truth_comparison_ {false}
 
std::vector< std::string > track_states_
 
std::shared_ptr< std::vector< ldmx::Track > > truth_track_collection_ {nullptr}
 
std::shared_ptr< std::vector< ldmx::SimTrackerHit > > ecal_scoring_hits_ {nullptr}
 
std::shared_ptr< std::vector< ldmx::SimTrackerHit > > target_scoring_hits_
 
std::vector< ldmx::Track > unique_tracks_
 
std::vector< ldmx::Track > duplicate_tracks_
 
std::vector< ldmx::Track > fake_tracks_
 
std::map< int, int > pidmap_
 

Additional Inherited Members

- Protected Member Functions inherited from framework::EventProcessor
void abortEvent ()
 Abort the event immediately.
 
- Protected Attributes inherited from framework::EventProcessor
HistogramPool histograms_
 helper object for making and filling histograms
 
NtupleManager & ntuple_ {NtupleManager::getInstance()}
 Manager for any ntuples.
 
logging::logger the_log_
 The logger for this EventProcessor.
 

Detailed Description

Definition at line 23 of file TrackingRecoDQM.h.

Constructor & Destructor Documentation

◆ TrackingRecoDQM()

tracking::dqm::TrackingRecoDQM::TrackingRecoDQM ( const std::string & name,
framework::Process & process )
inline

Definition at line 25 of file TrackingRecoDQM.h.

26 : framework::Analyzer(name, process) {};
Base class for a module which does not produce a data product.
virtual void process(Event &event) final
Processing an event for an Analyzer is calling analyze.

Member Function Documentation

◆ analyze()

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

Process the event and make histograms or summaries.

Parameters
eventThe Event to analyze

Implements framework::Analyzer.

Definition at line 42 of file TrackingRecoDQM.cxx.

42 {
43 ldmx_log(trace) << "DQM Reading in:" << track_collection_;
44
45 if (!event.exists(track_collection_, track_collection_events_passname_)) {
46 ldmx_log(error) << "TrackCollection " << track_collection_
47 << " with pass = " << track_collection_events_passname_
48 << " not in event";
49 return;
50 }
51
52 auto tracks{
53 event.getCollection<ldmx::Track>(track_collection_, track_passname_)};
54
55 if (!event.exists(measurement_collection_, measurement_passname_)) {
56 ldmx_log(error) << "Measurement collection " << measurement_collection_
57 << " with pass = " << measurement_passname_
58 << " not in event";
59 return;
60 }
61
62 auto measurements{event.getCollection<ldmx::Measurement>(
63 measurement_collection_, measurement_passname_)};
64
65 // The truth track collection
66 if (event.exists(truth_collection_, truth_events_passname_)) {
67 truth_track_collection_ = std::make_shared<std::vector<ldmx::Track>>(
68 event.getCollection<ldmx::Track>(truth_collection_, truth_passname_));
69 do_truth_comparison_ = true;
70 }
71
72 // The scoring plane hits_
73 if (event.exists(ecal_sp_coll_name_, ecal_sp_passname_)) {
74 ecal_scoring_hits_ = std::make_shared<std::vector<ldmx::SimTrackerHit>>(
75 event.getCollection<ldmx::SimTrackerHit>(ecal_sp_coll_name_,
76 ecal_sp_passname_));
77 }
78
79 if (event.exists(target_sp_coll_name_, target_sp_passname_)) {
80 target_scoring_hits_ = std::make_shared<std::vector<ldmx::SimTrackerHit>>(
81 event.getCollection<ldmx::SimTrackerHit>(target_sp_coll_name_,
82 target_sp_passname_));
83 }
84
85 ldmx_log(debug) << "Do truth comparison::" << do_truth_comparison_;
86
87 if (do_truth_comparison_) {
88 sortTracks(tracks, unique_tracks_, duplicate_tracks_, fake_tracks_);
89 } else {
90 unique_tracks_ = tracks;
91 }
92
93 ldmx_log(debug) << "Filling histograms for " << tracks.size() << " tracks";
94
95 // General Plots
96 histograms_.fill(title_ + "N_tracks", tracks.size());
97
98 if (!unique_tracks_.empty()) {
99 ldmx_log(debug) << "Track Monitoring on " << unique_tracks_.size()
100 << " Unique Tracks";
101 trackMonitoring(unique_tracks_, measurements, title_, true,
102 do_truth_comparison_);
103 }
104
105 // Fakes and duplicates
106 if (!duplicate_tracks_.empty()) {
107 ldmx_log(debug) << "Track Monitoring on " << duplicate_tracks_.size()
108 << " duplicates";
109 trackMonitoring(duplicate_tracks_, measurements, title_ + "dup_", false,
110 false);
111 }
112 if (!fake_tracks_.empty()) {
113 ldmx_log(debug) << "Track Monitoring on " << fake_tracks_.size()
114 << " fakes";
115 trackMonitoring(fake_tracks_, measurements, title_ + "fake_", false, false);
116 }
117
118 // Track Extrapolation to Ecal Monitoring
119 // trackStateMonitoring requires truth_track_collection_ to be available
120 ldmx_log(trace) << "Track Extrapolation to Ecal Monitoring";
121 if (do_truth_comparison_) {
122 if (std::find(track_states_.begin(), track_states_.end(), "target") !=
123 track_states_.end()) {
124 trackStateMonitoring(tracks, ldmx::AtTarget, "target");
125 }
126
127 if (std::find(track_states_.begin(), track_states_.end(), "ecal") !=
128 track_states_.end()) {
129 trackStateMonitoring(tracks, ldmx::AtECAL, "ecal");
130 }
131
132 if (std::find(track_states_.begin(), track_states_.end(), "beamOrigin") !=
133 track_states_.end()) {
134 trackStateMonitoring(tracks, ldmx::AtBeamOrigin, "beamOrigin");
135 }
136 }
137
138 // Technical Efficiency plots
139 if (do_truth_comparison_) {
140 ldmx_log(trace) << "Technical Efficiency plots";
141 efficiencyPlots(tracks, measurements, title_);
142 }
143
144 // Tagger Recoil Matching
145
146 // Clear the vectors
147 ldmx_log(trace) << "Clear the vectors";
148 unique_tracks_.clear();
149 duplicate_tracks_.clear();
150 fake_tracks_.clear();
151}
HistogramPool histograms_
helper object for making and filling histograms
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.
Represents a simulated tracker hit in the simulation.
Implementation of a track object.
Definition Track.h:54
void trackStateMonitoring(const std::vector< ldmx::Track > &tracks, ldmx::TrackStateType ts_type, const std::string &ts_title)
Monitoring plots for tracks extrapolated to the ECAL Scoring plane.

References framework::Event::exists(), framework::HistogramPool::fill(), framework::EventProcessor::histograms_, and trackStateMonitoring().

◆ configure()

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

Configure the analyzer using the given user specified parameters.

Parameters
parametersSet of parameters used to configure this analyzer.

Reimplemented from framework::EventProcessor.

Definition at line 10 of file TrackingRecoDQM.cxx.

10 {
11 track_collection_ = parameters.get<std::string>("track_collection");
12 truth_collection_ = parameters.get<std::string>("truth_collection");
13 measurement_collection_ =
14 parameters.get<std::string>("measurement_collection");
15 measurement_passname_ = parameters.get<std::string>("measurement_passname");
16
17 ecal_sp_coll_name_ = parameters.get<std::string>("ecal_sp_coll_name");
18 ecal_sp_passname_ = parameters.get<std::string>("ecal_sp_passname");
19 target_sp_coll_name_ = parameters.get<std::string>("target_sp_coll_name");
20 target_sp_passname_ = parameters.get<std::string>("target_sp_passname");
21 truth_passname_ = parameters.get<std::string>("truth_passname");
22 truth_events_passname_ = parameters.get<std::string>("truth_events_passname");
23 track_passname_ = parameters.get<std::string>("track_passname");
24 track_collection_events_passname_ =
25 parameters.get<std::string>("track_collection_events_passname");
26
27 title_ = parameters.get<std::string>("title", "tagger_trk_");
28 track_prob_cut_ = parameters.get<double>("trackProb_cut", 0.5);
29 subdetector_ = parameters.get<std::string>("subdetector", "Tagger");
30 track_states_ = parameters.get<std::vector<std::string>>("track_states", {});
31
32 pidmap_[-321] = PIDBins::kminus;
33 pidmap_[321] = PIDBins::kplus;
34 pidmap_[-211] = PIDBins::piminus;
35 pidmap_[211] = PIDBins::piplus;
36 pidmap_[11] = PIDBins::electron;
37 pidmap_[-11] = PIDBins::positron;
38 pidmap_[2212] = PIDBins::proton;
39 pidmap_[-2212] = PIDBins::antiproton;
40}
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75

References framework::config::Parameters::get().

◆ efficiencyPlots()

void tracking::dqm::TrackingRecoDQM::efficiencyPlots ( const std::vector< ldmx::Track > & tracks,
const std::vector< ldmx::Measurement > & measurements,
const std::string & title )

Definition at line 157 of file TrackingRecoDQM.cxx.

160 {
161 // Do all truth track plots - denominator
162
163 histograms_.fill(title + "truth_N_tracks", truth_track_collection_->size());
164 for (auto& truth_trk : *(truth_track_collection_)) {
165 auto truth_phi = truth_trk.getPhi();
166 auto truth_d0 = truth_trk.getD0();
167 auto truth_z0 = truth_trk.getZ0();
168 auto truth_theta = truth_trk.getTheta();
169 auto truth_qop = truth_trk.getQoP();
170 auto truth_p = 1000. / abs(truth_trk.getQoP()); // MeV
171 auto truth_n_hits = truth_trk.getNhits();
172
173 auto truth_mom = truth_trk.getMomentumAtTarget();
174 double truth_pt_beam{0.}, truth_beam_angle{0.};
175 if (truth_mom.size() == 3) {
176 truth_pt_beam =
177 std::sqrt(truth_mom[0] * truth_mom[0] + truth_mom[1] * truth_mom[1]);
178 truth_beam_angle = std::atan2(truth_pt_beam, truth_mom[2]);
179 }
180
181 histograms_.fill(title + "truth_nHits", truth_n_hits);
182 histograms_.fill(title + "truth_d0", truth_d0);
183 histograms_.fill(title + "truth_z0", truth_z0);
184 histograms_.fill(title + "truth_phi", truth_phi);
185 histograms_.fill(title + "truth_theta", truth_theta);
186 histograms_.fill(title + "truth_qop", truth_qop);
187 histograms_.fill(title + "truth_p", truth_p);
188 histograms_.fill(title + "truth_beam_angle", truth_beam_angle);
189
190 if (pidmap_.count(truth_trk.getPdgID()) != 0) {
191 histograms_.fill(title + "truth_PID", pidmap_[truth_trk.getPdgID()]);
192
193 // TODO do this properly.
194
195 if (pidmap_[truth_trk.getPdgID()] == PIDBins::kminus) {
196 histograms_.fill(title + "truth_kminus_p", truth_p);
197 }
198
199 if (pidmap_[truth_trk.getPdgID()] == PIDBins::kplus) {
200 histograms_.fill(title + "truth_kplus_p", truth_p);
201 }
202
203 if (pidmap_[truth_trk.getPdgID()] == PIDBins::piminus) {
204 histograms_.fill(title + "truth_piminus_p", truth_p);
205 }
206
207 if (pidmap_[truth_trk.getPdgID()] == PIDBins::piplus) {
208 histograms_.fill(title + "truth_piplus_p", truth_p);
209 }
210
211 if (pidmap_[truth_trk.getPdgID()] == PIDBins::electron) {
212 histograms_.fill(title + "truth_electron_p", truth_p);
213 }
214
215 if (pidmap_[truth_trk.getPdgID()] == PIDBins::positron) {
216 histograms_.fill(title + "truth_positron_p", truth_p);
217 }
218
219 if (pidmap_[truth_trk.getPdgID()] == PIDBins::proton) {
220 histograms_.fill(title + "truth_proton_p", truth_p);
221 }
222 }
223
224 } // loop on truth tracks
225
226 for (auto& track : tracks) {
227 // Match the tracks to truth
228 ldmx::Track* truth_trk = nullptr;
229
230 auto it = std::find_if(truth_track_collection_->begin(),
231 truth_track_collection_->end(),
232 [&](const ldmx::Track& tt) {
233 return tt.getTrackID() == track.getTrackID();
234 });
235
236 double track_truth_prob = track.getTruthProb();
237
238 if (it != truth_track_collection_->end() &&
239 track_truth_prob >= track_prob_cut_)
240 truth_trk = &(*it);
241
242 // Match not found, go to next track
243 if (!truth_trk) continue;
244
245 auto truth_phi = truth_trk->getPhi();
246 auto truth_d0 = truth_trk->getD0();
247 auto truth_z0 = truth_trk->getZ0();
248 auto truth_theta = truth_trk->getTheta();
249 auto truth_qop = truth_trk->getQoP();
250 auto truth_p = 1000. / abs(truth_trk->getQoP()); // MeV
251
252 auto truth_mom = truth_trk->getMomentumAtTarget();
253 double truth_pt_beam{0.}, truth_beam_angle{0.};
254 if (truth_mom.size() == 3) {
255 truth_pt_beam =
256 std::sqrt(truth_mom[0] * truth_mom[0] + truth_mom[1] * truth_mom[1]);
257 truth_beam_angle = std::atan2(truth_pt_beam, truth_mom[2]);
258 }
259
260 // Fill reco plots for efficiencies - numerator. The quantities are truth
261 histograms_.fill(title + "match_prob", track_truth_prob);
262 histograms_.fill(title + "match_d0", truth_d0);
263 histograms_.fill(title + "match_z0", truth_z0);
264 histograms_.fill(title + "match_phi", truth_phi);
265 histograms_.fill(title + "match_theta", truth_theta);
266 histograms_.fill(title + "match_p", truth_p);
267 histograms_.fill(title + "match_qop", truth_qop);
268 histograms_.fill(title + "match_beam_angle", truth_beam_angle);
269 histograms_.fill(title + "match_nHits", measurements.size());
270 auto dedx_measurements = track.getDedxMeasurements();
271 auto measurement_idxs = track.getMeasurementsIdxs();
272 for (size_t i = 0; i < measurement_idxs.size(); ++i) {
273 histograms_.fill(title + "match_layers_hit",
274 measurements.at(measurement_idxs[i]).getLayer());
275 // Add histogram of the measurement dE/dx
276 if (i < dedx_measurements.size()) {
277 histograms_.fill(title + "match_measurement_dedx",
278 dedx_measurements[i]);
279 }
280 }
281
282 // For some particles
283
284 if (pidmap_.count(truth_trk->getPdgID()) != 0) {
285 histograms_.fill(title + "match_PID", pidmap_[truth_trk->getPdgID()]);
286
287 // TODO do this properly.
288
289 if (pidmap_[truth_trk->getPdgID()] == PIDBins::kminus) {
290 histograms_.fill(title + "match_kminus_p", truth_p);
291 }
292
293 if (pidmap_[truth_trk->getPdgID()] == PIDBins::kplus) {
294 histograms_.fill(title + "match_kplus_p", truth_p);
295 }
296
297 if (pidmap_[truth_trk->getPdgID()] == PIDBins::piminus) {
298 histograms_.fill(title + "match_piminus_p", truth_p);
299 }
300
301 if (pidmap_[truth_trk->getPdgID()] == PIDBins::piplus) {
302 histograms_.fill(title + "match_piplus_p", truth_p);
303 }
304
305 if (pidmap_[truth_trk->getPdgID()] == PIDBins::electron) {
306 histograms_.fill(title + "match_electron_p", truth_p);
307 }
308
309 if (pidmap_[truth_trk->getPdgID()] == PIDBins::positron) {
310 histograms_.fill(title + "match_positron_p", truth_p);
311 }
312
313 if (pidmap_[truth_trk->getPdgID()] == PIDBins::proton) {
314 histograms_.fill(title + "match_proton_p", truth_p);
315 }
316 }
317 } // Loop on tracks
318
319} // Efficiency plots
std::vector< double > getMomentumAtTarget() const
Returns the momentum (px, py, pz) in MeV in the LDMX global frame from the AtTarget TrackState.
Definition Track.h:220

◆ onProcessEnd()

void tracking::dqm::TrackingRecoDQM::onProcessEnd ( )
overridevirtual

Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.

Reimplemented from framework::EventProcessor.

Definition at line 153 of file TrackingRecoDQM.cxx.

153 {
154 // Produce the efficiency plots. (TODO::Switch to TEfficiency instead)
155}

◆ sortTracks()

void tracking::dqm::TrackingRecoDQM::sortTracks ( const std::vector< ldmx::Track > & tracks,
std::vector< ldmx::Track > & uniqueTracks,
std::vector< ldmx::Track > & duplicateTracks,
std::vector< ldmx::Track > & fakeTracks )

Definition at line 648 of file TrackingRecoDQM.cxx.

651 {
652 // Create a copy of the const vector so we can sort it
653 std::vector<ldmx::Track> sorted_tracks = tracks;
654
655 // Sort the vector of Track objects based on their trackID member
656 std::sort(sorted_tracks.begin(), sorted_tracks.end(),
657 [](ldmx::Track& t1, ldmx::Track& t2) {
658 return t1.getTrackID() < t2.getTrackID();
659 });
660
661 // Loop over the sorted vector of Track objects
662 for (size_t i = 0; i < sorted_tracks.size(); i++) {
663 if (sorted_tracks[i].getTruthProb() < track_prob_cut_)
664 fakeTracks.push_back(sorted_tracks[i]);
665 else { // not a fake track
666 // If this is the first Track object with this trackID, add it to the
667 // uniqueTracks vector directly
668 if (uniqueTracks.size() == 0 ||
669 sorted_tracks[i].getTrackID() != sorted_tracks[i - 1].getTrackID()) {
670 uniqueTracks.push_back(sorted_tracks[i]);
671 }
672 // Otherwise, add it to the duplicateTracks vector if its truthProb is
673 // lower than the existing Track object Otherwise, if the truthProbability
674 // is higher than the track stored in uniqueTracks, put it in uniqueTracks
675 // and move the uniqueTracks.back to duplicateTracks.
676 else if (sorted_tracks[i].getTruthProb() >
677 uniqueTracks.back().getTruthProb()) {
678 duplicateTracks.push_back(uniqueTracks.back());
679 uniqueTracks.back() = sorted_tracks[i];
680 }
681 // Otherwise, add it to the duplicateTracks vector
682 else {
683 duplicateTracks.push_back(sorted_tracks[i]);
684 }
685 } // a real track
686 } // loop on sorted tracks
687 // The total number of elements in the uniqueTracks and duplicateTracks
688 // vectors should be equal to the number of elements in the original tracks
689 // vector
690 if (uniqueTracks.size() + duplicateTracks.size() + fakeTracks.size() !=
691 tracks.size()) {
692 std::cerr << "Error: unique and duplicate tracks vectors do not add up to "
693 "original tracks vector";
694 return;
695 }
696
697 // Iterate through the uniqueTracks vector and duplicateTracks vector
698 ldmx_log(trace) << "Unique tracks:";
699 for (const ldmx::Track& track : uniqueTracks) {
700 ldmx_log(trace) << "\tTrack ID: " << track.getTrackID()
701 << ", Truth Prob: " << track.getTruthProb();
702 }
703 ldmx_log(trace) << "Duplicate tracks:";
704 for (const ldmx::Track& track : duplicateTracks) {
705 ldmx_log(trace) << "\tTrack ID: " << track.getTrackID()
706 << ", Truth Prob: " << track.getTruthProb();
707 }
708 ldmx_log(trace) << "Fake tracks:";
709 for (const ldmx::Track& track : fakeTracks) {
710 ldmx_log(trace) << "\tTrack ID: " << track.getTrackID()
711 << ", Truth Prob: " << track.getTruthProb();
712 }
713}

◆ trackMonitoring()

void tracking::dqm::TrackingRecoDQM::trackMonitoring ( const std::vector< ldmx::Track > & tracks,
const std::vector< ldmx::Measurement > & measurements,
const std::string title,
const bool & doDetail,
const bool & doTruth )

Definition at line 321 of file TrackingRecoDQM.cxx.

324 {
325 for (auto& track : tracks) {
326 // Perigee track parameters
327 auto trk_d0 = track.getD0();
328 auto trk_z0 = track.getZ0();
329 auto trk_qop = track.getQoP();
330 auto trk_theta = track.getTheta();
331 auto trk_phi = track.getPhi();
332 auto trk_p = 1000. / abs(trk_qop); // MeV
333 auto dedx_measurements = track.getDedxMeasurements();
334 auto measurement_idxs = track.getMeasurementsIdxs();
335 for (size_t i = 0; i < measurement_idxs.size(); ++i) {
336 histograms_.fill(title + "layers_hit",
337 measurements.at(measurement_idxs[i]).getLayer());
338 // Add histogram of the measurement dE/dx
339 if (i < dedx_measurements.size()) {
340 histograms_.fill(title + "measurement_dedx", dedx_measurements[i]);
341 }
342 }
343
344 // Per-layer unbiased U-residuals — only filled for the main unique-track
345 // call (title == title_). Fakes/duplicates use a different title prefix
346 // and do not have these histograms declared.
347 //
348 // Algebraic leave-one-out unbiasing (NIM A 262, 444, 1987):
349 // r_smooth = m - x_smooth
350 // denom = V - C (V = cov_uu, C = smoothed cov[loc0,loc0])
351 // r_ubs = V / denom * r_smooth
352 // pull = r_smooth / sqrt(denom)
353 if (title == title_) {
354 const auto& sm_loc0 = track.getSmoothedLoc0();
355 const auto& sm_cov = track.getSmoothedCovLoc0();
356 for (size_t i = 0; i < measurement_idxs.size(); ++i) {
357 if (i >= sm_loc0.size()) break;
358 const auto& meas = measurements.at(measurement_idxs[i]);
359 int layer = meas.getLayer();
360 float meas_u = meas.getLocalPosition()[0];
361 float v = meas.getLocalCovariance()[0]; // cov_uu
362 float c = sm_cov[i]; // smoothed cov[loc0, loc0]
363 float denom = v - c;
364 if (denom <= 0.f) continue; // degenerate — skip
365 float r_smooth = meas_u - sm_loc0[i];
366 float res_ubs = r_smooth * v / denom;
367 float pull_ubs = r_smooth / std::sqrt(denom);
368 histograms_.fill(title_ + "unbiased_res_u_l" + std::to_string(layer),
369 res_ubs);
370 histograms_.fill(title_ + "unbiased_pull_u_l" + std::to_string(layer),
371 pull_ubs);
372 }
373 }
374
375 auto trk_mom = track.getMomentumAtTarget();
376 // getMomentumAtTarget() returns MeV (LDMX convention)
377 double px_ldmx{0.}, py_ldmx{0.}, pz_ldmx{0.};
378 double pt_bending{0.}, pt_beam{0.};
379 if (trk_mom.size() == 3) {
380 px_ldmx = trk_mom[0]; // MeV
381 py_ldmx = trk_mom[1];
382 pz_ldmx = trk_mom[2];
383 // Bending-plane pT: horizontal (x_ldmx) + downstream (z_ldmx)
384 pt_bending = std::sqrt(px_ldmx * px_ldmx + pz_ldmx * pz_ldmx);
385 // Transverse pT perpendicular to beam: horizontal + vertical
386 pt_beam = std::sqrt(px_ldmx * px_ldmx + py_ldmx * py_ldmx);
387 }
388
389 // Covariance matrix
390 Acts::BoundMatrix cov =
391 tracking::sim::utils::unpackCov(track.getPerigeeCov());
392
393 double sigmad0 = sqrt(
394 cov(Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc0));
395 double sigmaz0 = sqrt(
396 cov(Acts::BoundIndices::eBoundLoc1, Acts::BoundIndices::eBoundLoc1));
397 double sigmaphi =
398 sqrt(cov(Acts::BoundIndices::eBoundPhi, Acts::BoundIndices::eBoundPhi));
399 double sigmatheta = sqrt(
400 cov(Acts::BoundIndices::eBoundTheta, Acts::BoundIndices::eBoundTheta));
401 double sigmaqop = sqrt(cov(Acts::BoundIndices::eBoundQOverP,
402 Acts::BoundIndices::eBoundQOverP));
403 double sigmap =
404 (1000. / trk_qop) * (1000. / trk_qop) * sigmaqop / 1000.; // MeV
405
406 histograms_.fill(title + "d0", trk_d0);
407 histograms_.fill(title + "z0", trk_z0);
408 histograms_.fill(title + "qop", trk_qop);
409 histograms_.fill(title + "phi", trk_phi);
410 histograms_.fill(title + "theta", trk_theta);
411 histograms_.fill(title + "p", trk_p);
412
413 if (doDetail) {
414 histograms_.fill(title + "px", px_ldmx);
415 histograms_.fill(title + "py", py_ldmx);
416 histograms_.fill(title + "pz", pz_ldmx);
417
418 histograms_.fill(title + "pt_bending", pt_bending);
419 histograms_.fill(title + "pt_beam", pt_beam);
420
421 histograms_.fill(title + "nHits", track.getNhits());
422 histograms_.fill(title + "Chi2", track.getChi2());
423 histograms_.fill(title + "ndf", track.getNdf());
424 histograms_.fill(title + "Chi2_per_ndf",
425 track.getChi2() / track.getNdf());
426 histograms_.fill(title + "nShared", track.getNsharedHits());
427
428 histograms_.fill(title + "d0_err", sigmad0);
429 histograms_.fill(title + "z0_err", sigmaz0);
430 histograms_.fill(title + "phi_err", sigmaphi);
431 histograms_.fill(title + "theta_err", sigmatheta);
432 histograms_.fill(title + "qop_err", sigmaqop);
433 histograms_.fill(title + "p_err", sigmap);
434
435 // 2D Error plots (p in MeV)
436 histograms_.fill(title + "d0_err_vs_p", trk_p, sigmad0);
437 histograms_.fill(title + "z0_err_vs_p", trk_p, sigmaz0);
438 histograms_.fill(title + "p_err_vs_p", trk_p, sigmap);
439
440 if (track.getNhits() == 8)
441 histograms_.fill(title + "p_err_vs_p_8hits", trk_p, sigmap);
442 else if (track.getNhits() == 9)
443 histograms_.fill(title + "p_err_vs_p_9hits", trk_p, sigmap);
444 else if (track.getNhits() == 10)
445 histograms_.fill(title + "p_err_vs_p_10hits", trk_p, sigmap);
446 }
447
448 if (doTruth) {
449 // Match to the truth track
450 ldmx::Track* truth_trk = nullptr;
451
452 auto it = std::find_if(truth_track_collection_->begin(),
453 truth_track_collection_->end(),
454 [&](const ldmx::Track& tt) {
455 return tt.getTrackID() == track.getTrackID();
456 });
457
458 double track_truth_prob = track.getTruthProb();
459
460 if (it != truth_track_collection_->end() &&
461 track_truth_prob >= track_prob_cut_)
462 truth_trk = &(*it);
463
464 // Found matched track
465 if (truth_trk) {
466 auto truth_d0 = truth_trk->getD0();
467 auto truth_z0 = truth_trk->getZ0();
468 auto truth_phi = truth_trk->getPhi();
469 auto truth_theta = truth_trk->getTheta();
470 auto truth_qop = truth_trk->getQoP();
471 auto truth_p = 1000. / abs(truth_trk->getQoP()); // MeV
472 auto truth_mom = truth_trk->getMomentumAtTarget();
473 // getMomentumAtTarget() returns MeV (LDMX convention)
474 double truth_pt_beam{0.};
475 if (truth_mom.size() == 3) {
476 truth_pt_beam = std::sqrt(truth_mom[0] * truth_mom[0] +
477 truth_mom[1] * truth_mom[1]);
478 }
479
480 // histograms_.fill(title+"truth_d0", truth_d0);
481 // histograms_.fill(title+"truth_z0", truth_z0);
482 // histograms_.fill(title+"truth_phi", truth_phi);
483 // histograms_.fill(title+"truth_theta",truth_theta);
484 // histograms_.fill(title+"truth_qop", truth_qop);
485 // histograms_.fill(title+"truth_p", truth_p);
486
487 double res_d0 = trk_d0 - truth_d0;
488 double res_z0 = trk_z0 - truth_z0;
489 double res_phi = trk_phi - truth_phi;
490 double res_theta = trk_theta - truth_theta;
491 double res_qop = trk_qop - truth_qop;
492 double res_p = trk_p - truth_p;
493 double res_pt_beam = pt_beam - truth_pt_beam;
494
495 histograms_.fill(title + "res_d0", res_d0);
496 histograms_.fill(title + "res_z0", res_z0);
497 histograms_.fill(title + "res_phi", res_phi);
498 histograms_.fill(title + "res_theta", res_theta);
499 histograms_.fill(title + "res_qop", res_qop);
500 histograms_.fill(title + "res_p", res_p);
501 histograms_.fill(title + "res_pt_beam", res_pt_beam);
502
503 double pull_d0 = res_d0 / sigmad0;
504 double pull_z0 = res_z0 / sigmaz0;
505 double pull_phi = res_phi / sigmaphi;
506 double pull_theta = res_theta / sigmatheta;
507 double pull_qop = res_qop / sigmaqop;
508 double pull_p = res_p / sigmap;
509
510 histograms_.fill(title + "pull_d0", pull_d0);
511 histograms_.fill(title + "pull_z0", pull_z0);
512 histograms_.fill(title + "pull_phi", pull_phi);
513 histograms_.fill(title + "pull_theta", pull_theta);
514 histograms_.fill(title + "pull_qop", pull_qop);
515 histograms_.fill(title + "pull_p", pull_p);
516
517 // Error plots from residuals
518
519 histograms_.fill(title + "res_p_vs_p", truth_p, res_p);
520
521 histograms_.fill(title + "res_qop_vs_p", truth_p, res_qop);
522 histograms_.fill(title + "res_d0_vs_p", truth_p, res_d0);
523 histograms_.fill(title + "res_z0_vs_p", truth_p, res_z0);
524 histograms_.fill(title + "res_phi_vs_p", truth_p, res_phi);
525 histograms_.fill(title + "res_theta_vs_p", truth_p, res_theta);
526
527 histograms_.fill(title + "pull_qop_vs_p", truth_p, pull_qop);
528 histograms_.fill(title + "pull_d0_vs_p", truth_p, pull_d0);
529 histograms_.fill(title + "pull_z0_vs_p", truth_p, pull_z0);
530 histograms_.fill(title + "pull_phi_vs_p", truth_p, pull_phi);
531 histograms_.fill(title + "pull_theta_vs_p", truth_p, pull_theta);
532
533 if (track.getNhits() == 8)
534 histograms_.fill(title + "res_p_vs_p_8hits", truth_p, res_p);
535 else if (track.getNhits() == 9)
536 histograms_.fill(title + "res_p_vs_p_9hits", truth_p, res_p);
537 else if (track.getNhits() == 10)
538 histograms_.fill(title + "res_p_vs_p_10hits", truth_p, res_p);
539
540 histograms_.fill(title + "res_pt_beam_vs_p", truth_pt_beam,
541 res_pt_beam);
542
543 } // found matched track
544 } // do TruthComparison
545 } // loop on tracks
546
547} // Track Monitoring

◆ trackStateMonitoring()

void tracking::dqm::TrackingRecoDQM::trackStateMonitoring ( const std::vector< ldmx::Track > & tracks,
ldmx::TrackStateType ts_type,
const std::string & ts_title )

Monitoring plots for tracks extrapolated to the ECAL Scoring plane.

This aims Tracks will be truth matched first to get the trackID. The hit with the trackID

Definition at line 549 of file TrackingRecoDQM.cxx.

551 {
552 for (auto& track : tracks) {
553 // Match the tracks to truth
554 ldmx::Track* truth_trk = nullptr;
555
556 auto it = std::find_if(truth_track_collection_->begin(),
557 truth_track_collection_->end(),
558 [&](const ldmx::Track& tt) {
559 return tt.getTrackID() == track.getTrackID();
560 });
561
562 double track_truth_prob = track.getTruthProb();
563
564 if (it != truth_track_collection_->end() &&
565 track_truth_prob >= track_prob_cut_)
566 truth_trk = &(*it);
567
568 // Match not found, skip track
569 if (!truth_trk) continue;
570
571 auto trk_ts = track.getTrackState(ts_type);
572 auto truth_ts = truth_trk->getTrackState(ts_type);
573
574 if (!trk_ts.has_value()) continue;
575 if (!truth_ts.has_value()) continue;
576
577 const ldmx::Track::TrackState& target_state = trk_ts.value();
578 const ldmx::Track::TrackState& truth_target_state = truth_ts.value();
579
580 // Check that the covariance is filled
581 if (target_state.pos_mom_cov_.size() < 21) continue;
582
583 // Sigma from Cartesian position covariance (LDMX frame):
584 // pos_mom_cov_ upper-triangle layout: xx=0, yy=6
585 double sigmaloc0 = std::sqrt(target_state.pos_mom_cov_[0]); // sigma_x
586 double sigmaloc1 = std::sqrt(target_state.pos_mom_cov_[6]); // sigma_y
587
588 double trk_qop = track.getQoP();
589 double trk_p = 1000. / abs(trk_qop); // MeV
590
591 // loc0/loc1 = x/y position at the surface in LDMX global frame
592 double track_state_loc0 = target_state.pos_[0];
593 double track_state_loc1 = target_state.pos_[1];
594
595 double truth_state_loc0 = truth_target_state.pos_[0];
596 double truth_state_loc1 = truth_target_state.pos_[1];
597
598 histograms_.fill(title_ + "trk_" + ts_title + "_loc0", track_state_loc0);
599 histograms_.fill(title_ + "trk_" + ts_title + "_loc1", track_state_loc1);
600 histograms_.fill(title_ + ts_title + "_truth_loc0", truth_state_loc0);
601 histograms_.fill(title_ + ts_title + "_truth_loc1", truth_state_loc1);
602
603 // TH1F residuals
605 title_ + "trk_" + ts_title + "_loc0-truth_" + ts_title + "_loc0",
606 track_state_loc0 - truth_state_loc0);
608 title_ + "trk_" + ts_title + "_loc1-truth_" + ts_title + "_loc1",
609 track_state_loc1 - truth_state_loc1);
610
611 // TH1F The pulls of loc0 and loc1
612 histograms_.fill(title_ + ts_title + "_Pulls_of_loc0",
613 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
614 histograms_.fill(title_ + ts_title + "_Pulls_of_loc1",
615 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
616
617 // TODO:: TH1F The pulls of phi, theta, qop
618
619 // TH2F residual vs Nhits
620 histograms_.fill(title_ + ts_title + "_res_loc0-vs-N_hits",
621 track.getNhits(), track_state_loc0 - truth_state_loc0);
622 histograms_.fill(title_ + ts_title + "_res_loc1-vs-N_hits",
623 track.getNhits(), track_state_loc1 - truth_state_loc1);
624
625 // TH2F pulls vs Nhits
626 histograms_.fill(title_ + ts_title + "_pulls_loc0-vs-N_hits",
627 track.getNhits(),
628 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
629 histograms_.fill(title_ + ts_title + "_pulls_loc1-vs-N_hits",
630 track.getNhits(),
631 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
632
633 // TH2F residual vs trk_p
634 histograms_.fill(title_ + ts_title + "_res_loc0-vs-trk_p", trk_p,
635 track_state_loc0 - truth_state_loc0);
636 histograms_.fill(title_ + ts_title + "_res_loc1-vs-trk_p", trk_p,
637 track_state_loc1 - truth_state_loc1);
638
639 // TH2F pulls vs trk_p
640 histograms_.fill(title_ + ts_title + "_pulls_loc0-vs-trk_p", trk_p,
641 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
642 histograms_.fill(title_ + ts_title + "_pulls_loc1-vs-trk_p", trk_p,
643 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
644
645 } // loop on tracks
646}

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

Referenced by analyze().

Member Data Documentation

◆ do_truth_comparison_

bool tracking::dqm::TrackingRecoDQM::do_truth_comparison_ {false}
private

Definition at line 85 of file TrackingRecoDQM.h.

85{false};

◆ duplicate_tracks_

std::vector<ldmx::Track> tracking::dqm::TrackingRecoDQM::duplicate_tracks_
private

Definition at line 103 of file TrackingRecoDQM.h.

◆ ecal_scoring_hits_

std::shared_ptr<std::vector<ldmx::SimTrackerHit> > tracking::dqm::TrackingRecoDQM::ecal_scoring_hits_ {nullptr}
private

Definition at line 92 of file TrackingRecoDQM.h.

92{nullptr};

◆ ecal_sp_coll_name_

std::string tracking::dqm::TrackingRecoDQM::ecal_sp_coll_name_
private

Definition at line 73 of file TrackingRecoDQM.h.

◆ ecal_sp_passname_

std::string tracking::dqm::TrackingRecoDQM::ecal_sp_passname_
private

Definition at line 74 of file TrackingRecoDQM.h.

◆ fake_tracks_

std::vector<ldmx::Track> tracking::dqm::TrackingRecoDQM::fake_tracks_
private

Definition at line 105 of file TrackingRecoDQM.h.

◆ measurement_collection_

std::string tracking::dqm::TrackingRecoDQM::measurement_collection_
private

Definition at line 70 of file TrackingRecoDQM.h.

◆ measurement_passname_

std::string tracking::dqm::TrackingRecoDQM::measurement_passname_
private

Definition at line 71 of file TrackingRecoDQM.h.

◆ pidmap_

std::map<int, int> tracking::dqm::TrackingRecoDQM::pidmap_
private

Definition at line 108 of file TrackingRecoDQM.h.

◆ subdetector_

std::string tracking::dqm::TrackingRecoDQM::subdetector_ {"Tagger"}
private

Definition at line 84 of file TrackingRecoDQM.h.

84{"Tagger"};

◆ target_scoring_hits_

std::shared_ptr<std::vector<ldmx::SimTrackerHit> > tracking::dqm::TrackingRecoDQM::target_scoring_hits_
private
Initial value:
{
nullptr}

Definition at line 95 of file TrackingRecoDQM.h.

95 {
96 nullptr};

◆ target_sp_coll_name_

std::string tracking::dqm::TrackingRecoDQM::target_sp_coll_name_
private

Definition at line 75 of file TrackingRecoDQM.h.

◆ target_sp_passname_

std::string tracking::dqm::TrackingRecoDQM::target_sp_passname_
private

Definition at line 76 of file TrackingRecoDQM.h.

◆ title_

std::string tracking::dqm::TrackingRecoDQM::title_ {"tagger_trk_"}
private

Definition at line 82 of file TrackingRecoDQM.h.

82{"tagger_trk_"};

◆ track_collection_

std::string tracking::dqm::TrackingRecoDQM::track_collection_
private

Definition at line 68 of file TrackingRecoDQM.h.

◆ track_collection_events_passname_

std::string tracking::dqm::TrackingRecoDQM::track_collection_events_passname_
private

Definition at line 77 of file TrackingRecoDQM.h.

◆ track_passname_

std::string tracking::dqm::TrackingRecoDQM::track_passname_
private

Definition at line 78 of file TrackingRecoDQM.h.

◆ track_prob_cut_

double tracking::dqm::TrackingRecoDQM::track_prob_cut_ {0.5}
private

Definition at line 83 of file TrackingRecoDQM.h.

83{0.5};

◆ track_states_

std::vector<std::string> tracking::dqm::TrackingRecoDQM::track_states_
private

Definition at line 86 of file TrackingRecoDQM.h.

◆ truth_collection_

std::string tracking::dqm::TrackingRecoDQM::truth_collection_
private

Definition at line 69 of file TrackingRecoDQM.h.

◆ truth_events_passname_

std::string tracking::dqm::TrackingRecoDQM::truth_events_passname_
private

Definition at line 79 of file TrackingRecoDQM.h.

◆ truth_passname_

std::string tracking::dqm::TrackingRecoDQM::truth_passname_
private

Definition at line 80 of file TrackingRecoDQM.h.

◆ truth_track_collection_

std::shared_ptr<std::vector<ldmx::Track> > tracking::dqm::TrackingRecoDQM::truth_track_collection_ {nullptr}
private

Definition at line 89 of file TrackingRecoDQM.h.

89{nullptr};

◆ unique_tracks_

std::vector<ldmx::Track> tracking::dqm::TrackingRecoDQM::unique_tracks_
private

Definition at line 101 of file TrackingRecoDQM.h.


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