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::Trackunique_tracks_
 
std::vector< ldmx::Trackduplicate_tracks_
 
std::vector< ldmx::Trackfake_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
 
NtupleManagerntuple_ {NtupleManager::getInstance()}
 Manager for any ntuples.
 
logging::logger the_log_
 The logger for this EventProcessor.
 

Detailed Description

Definition at line 28 of file TrackingRecoDQM.h.

Constructor & Destructor Documentation

◆ TrackingRecoDQM()

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

Definition at line 30 of file TrackingRecoDQM.h.

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 37 of file TrackingRecoDQM.cxx.

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

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

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 152 of file TrackingRecoDQM.cxx.

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

◆ 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 148 of file TrackingRecoDQM.cxx.

148 {
149 // Produce the efficiency plots. (TODO::Switch to TEfficiency instead)
150}

◆ 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 612 of file TrackingRecoDQM.cxx.

615 {
616 // Create a copy of the const vector so we can sort it
617 std::vector<ldmx::Track> sorted_tracks = tracks;
618
619 // Sort the vector of Track objects based on their trackID member
620 std::sort(sorted_tracks.begin(), sorted_tracks.end(),
621 [](ldmx::Track& t1, ldmx::Track& t2) {
622 return t1.getTrackID() < t2.getTrackID();
623 });
624
625 // Loop over the sorted vector of Track objects
626 for (size_t i = 0; i < sorted_tracks.size(); i++) {
627 if (sorted_tracks[i].getTruthProb() < track_prob_cut_)
628 fakeTracks.push_back(sorted_tracks[i]);
629 else { // not a fake track
630 // If this is the first Track object with this trackID, add it to the
631 // uniqueTracks vector directly
632 if (uniqueTracks.size() == 0 ||
633 sorted_tracks[i].getTrackID() != sorted_tracks[i - 1].getTrackID()) {
634 uniqueTracks.push_back(sorted_tracks[i]);
635 }
636 // Otherwise, add it to the duplicateTracks vector if its truthProb is
637 // lower than the existing Track object Otherwise, if the truthProbability
638 // is higher than the track stored in uniqueTracks, put it in uniqueTracks
639 // and move the uniqueTracks.back to duplicateTracks.
640 else if (sorted_tracks[i].getTruthProb() >
641 uniqueTracks.back().getTruthProb()) {
642 duplicateTracks.push_back(uniqueTracks.back());
643 uniqueTracks.back() = sorted_tracks[i];
644 }
645 // Otherwise, add it to the duplicateTracks vector
646 else {
647 duplicateTracks.push_back(sorted_tracks[i]);
648 }
649 } // a real track
650 } // loop on sorted tracks
651 // The total number of elements in the uniqueTracks and duplicateTracks
652 // vectors should be equal to the number of elements in the original tracks
653 // vector
654 if (uniqueTracks.size() + duplicateTracks.size() + fakeTracks.size() !=
655 tracks.size()) {
656 std::cerr << "Error: unique and duplicate tracks vectors do not add up to "
657 "original tracks vector";
658 return;
659 }
660
661 // Iterate through the uniqueTracks vector and duplicateTracks vector
662 ldmx_log(trace) << "Unique tracks:";
663 for (const ldmx::Track& track : uniqueTracks) {
664 ldmx_log(trace) << "\tTrack ID: " << track.getTrackID()
665 << ", Truth Prob: " << track.getTruthProb();
666 }
667 ldmx_log(trace) << "Duplicate tracks:";
668 for (const ldmx::Track& track : duplicateTracks) {
669 ldmx_log(trace) << "\tTrack ID: " << track.getTrackID()
670 << ", Truth Prob: " << track.getTruthProb();
671 }
672 ldmx_log(trace) << "Fake tracks:";
673 for (const ldmx::Track& track : fakeTracks) {
674 ldmx_log(trace) << "\tTrack ID: " << track.getTrackID()
675 << ", Truth Prob: " << track.getTruthProb();
676 }
677}

◆ 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 316 of file TrackingRecoDQM.cxx.

319 {
320 for (auto& track : tracks) {
321 // Perigee track parameters
322 auto trk_d0 = track.getD0();
323 auto trk_z0 = track.getZ0();
324 auto trk_qop = track.getQoP();
325 auto trk_theta = track.getTheta();
326 auto trk_phi = track.getPhi();
327 auto trk_p = 1000. / abs(trk_qop); // MeV
328 auto dedx_measurements = track.getDedxMeasurements();
329 auto measurement_idxs = track.getMeasurementsIdxs();
330 for (size_t i = 0; i < measurement_idxs.size(); ++i) {
331 histograms_.fill(title + "layers_hit",
332 measurements.at(measurement_idxs[i]).getLayer());
333 // Add histogram of the measurement dE/dx
334 if (i < dedx_measurements.size()) {
335 histograms_.fill(title + "measurement_dedx", dedx_measurements[i]);
336 }
337 }
338
339 auto trk_mom = track.getMomentumAtTarget();
340 // getMomentumAtTarget() returns MeV (LDMX convention)
341 double px_ldmx{0.}, py_ldmx{0.}, pz_ldmx{0.};
342 double pt_bending{0.}, pt_beam{0.};
343 if (trk_mom.size() == 3) {
344 px_ldmx = trk_mom[0]; // MeV
345 py_ldmx = trk_mom[1];
346 pz_ldmx = trk_mom[2];
347 // Bending-plane pT: horizontal (x_ldmx) + downstream (z_ldmx)
348 pt_bending = std::sqrt(px_ldmx * px_ldmx + pz_ldmx * pz_ldmx);
349 // Transverse pT perpendicular to beam: horizontal + vertical
350 pt_beam = std::sqrt(px_ldmx * px_ldmx + py_ldmx * py_ldmx);
351 }
352
353 // Covariance matrix
354 Acts::BoundSquareMatrix cov =
355 tracking::sim::utils::unpackCov(track.getPerigeeCov());
356
357 double sigmad0 = sqrt(
358 cov(Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc0));
359 double sigmaz0 = sqrt(
360 cov(Acts::BoundIndices::eBoundLoc1, Acts::BoundIndices::eBoundLoc1));
361 double sigmaphi =
362 sqrt(cov(Acts::BoundIndices::eBoundPhi, Acts::BoundIndices::eBoundPhi));
363 double sigmatheta = sqrt(
364 cov(Acts::BoundIndices::eBoundTheta, Acts::BoundIndices::eBoundTheta));
365 double sigmaqop = sqrt(cov(Acts::BoundIndices::eBoundQOverP,
366 Acts::BoundIndices::eBoundQOverP));
367 double sigmap =
368 (1000. / trk_qop) * (1000. / trk_qop) * sigmaqop / 1000.; // MeV
369
370 histograms_.fill(title + "d0", trk_d0);
371 histograms_.fill(title + "z0", trk_z0);
372 histograms_.fill(title + "qop", trk_qop);
373 histograms_.fill(title + "phi", trk_phi);
374 histograms_.fill(title + "theta", trk_theta);
375 histograms_.fill(title + "p", trk_p);
376
377 if (doDetail) {
378 histograms_.fill(title + "px", px_ldmx);
379 histograms_.fill(title + "py", py_ldmx);
380 histograms_.fill(title + "pz", pz_ldmx);
381
382 histograms_.fill(title + "pt_bending", pt_bending);
383 histograms_.fill(title + "pt_beam", pt_beam);
384
385 histograms_.fill(title + "nHits", track.getNhits());
386 histograms_.fill(title + "Chi2", track.getChi2());
387 histograms_.fill(title + "ndf", track.getNdf());
388 histograms_.fill(title + "Chi2_per_ndf",
389 track.getChi2() / track.getNdf());
390 histograms_.fill(title + "nShared", track.getNsharedHits());
391
392 histograms_.fill(title + "d0_err", sigmad0);
393 histograms_.fill(title + "z0_err", sigmaz0);
394 histograms_.fill(title + "phi_err", sigmaphi);
395 histograms_.fill(title + "theta_err", sigmatheta);
396 histograms_.fill(title + "qop_err", sigmaqop);
397 histograms_.fill(title + "p_err", sigmap);
398
399 // 2D Error plots (p in MeV)
400 histograms_.fill(title + "d0_err_vs_p", trk_p, sigmad0);
401 histograms_.fill(title + "z0_err_vs_p", trk_p, sigmaz0);
402 histograms_.fill(title + "p_err_vs_p", trk_p, sigmap);
403
404 if (track.getNhits() == 8)
405 histograms_.fill(title + "p_err_vs_p_8hits", trk_p, sigmap);
406 else if (track.getNhits() == 9)
407 histograms_.fill(title + "p_err_vs_p_9hits", trk_p, sigmap);
408 else if (track.getNhits() == 10)
409 histograms_.fill(title + "p_err_vs_p_10hits", trk_p, sigmap);
410 }
411
412 if (doTruth) {
413 // Match to the truth track
414 ldmx::Track* truth_trk = nullptr;
415
416 auto it = std::find_if(truth_track_collection_->begin(),
417 truth_track_collection_->end(),
418 [&](const ldmx::Track& tt) {
419 return tt.getTrackID() == track.getTrackID();
420 });
421
422 double track_truth_prob = track.getTruthProb();
423
424 if (it != truth_track_collection_->end() &&
425 track_truth_prob >= track_prob_cut_)
426 truth_trk = &(*it);
427
428 // Found matched track
429 if (truth_trk) {
430 auto truth_d0 = truth_trk->getD0();
431 auto truth_z0 = truth_trk->getZ0();
432 auto truth_phi = truth_trk->getPhi();
433 auto truth_theta = truth_trk->getTheta();
434 auto truth_qop = truth_trk->getQoP();
435 auto truth_p = 1000. / abs(truth_trk->getQoP()); // MeV
436 auto truth_mom = truth_trk->getMomentumAtTarget();
437 // getMomentumAtTarget() returns MeV (LDMX convention)
438 double truth_pt_beam{0.};
439 if (truth_mom.size() == 3) {
440 truth_pt_beam = std::sqrt(truth_mom[0] * truth_mom[0] +
441 truth_mom[1] * truth_mom[1]);
442 }
443
444 // histograms_.fill(title+"truth_d0", truth_d0);
445 // histograms_.fill(title+"truth_z0", truth_z0);
446 // histograms_.fill(title+"truth_phi", truth_phi);
447 // histograms_.fill(title+"truth_theta",truth_theta);
448 // histograms_.fill(title+"truth_qop", truth_qop);
449 // histograms_.fill(title+"truth_p", truth_p);
450
451 double res_d0 = trk_d0 - truth_d0;
452 double res_z0 = trk_z0 - truth_z0;
453 double res_phi = trk_phi - truth_phi;
454 double res_theta = trk_theta - truth_theta;
455 double res_qop = trk_qop - truth_qop;
456 double res_p = trk_p - truth_p;
457 double res_pt_beam = pt_beam - truth_pt_beam;
458
459 histograms_.fill(title + "res_d0", res_d0);
460 histograms_.fill(title + "res_z0", res_z0);
461 histograms_.fill(title + "res_phi", res_phi);
462 histograms_.fill(title + "res_theta", res_theta);
463 histograms_.fill(title + "res_qop", res_qop);
464 histograms_.fill(title + "res_p", res_p);
465 histograms_.fill(title + "res_pt_beam", res_pt_beam);
466
467 double pull_d0 = res_d0 / sigmad0;
468 double pull_z0 = res_z0 / sigmaz0;
469 double pull_phi = res_phi / sigmaphi;
470 double pull_theta = res_theta / sigmatheta;
471 double pull_qop = res_qop / sigmaqop;
472 double pull_p = res_p / sigmap;
473
474 histograms_.fill(title + "pull_d0", pull_d0);
475 histograms_.fill(title + "pull_z0", pull_z0);
476 histograms_.fill(title + "pull_phi", pull_phi);
477 histograms_.fill(title + "pull_theta", pull_theta);
478 histograms_.fill(title + "pull_qop", pull_qop);
479 histograms_.fill(title + "pull_p", pull_p);
480
481 // Error plots from residuals
482
483 histograms_.fill(title + "res_p_vs_p", truth_p, res_p);
484
485 histograms_.fill(title + "res_qop_vs_p", truth_p, res_qop);
486 histograms_.fill(title + "res_d0_vs_p", truth_p, res_d0);
487 histograms_.fill(title + "res_z0_vs_p", truth_p, res_z0);
488 histograms_.fill(title + "res_phi_vs_p", truth_p, res_phi);
489 histograms_.fill(title + "res_theta_vs_p", truth_p, res_theta);
490
491 histograms_.fill(title + "pull_qop_vs_p", truth_p, pull_qop);
492 histograms_.fill(title + "pull_d0_vs_p", truth_p, pull_d0);
493 histograms_.fill(title + "pull_z0_vs_p", truth_p, pull_z0);
494 histograms_.fill(title + "pull_phi_vs_p", truth_p, pull_phi);
495 histograms_.fill(title + "pull_theta_vs_p", truth_p, pull_theta);
496
497 if (track.getNhits() == 8)
498 histograms_.fill(title + "res_p_vs_p_8hits", truth_p, res_p);
499 else if (track.getNhits() == 9)
500 histograms_.fill(title + "res_p_vs_p_9hits", truth_p, res_p);
501 else if (track.getNhits() == 10)
502 histograms_.fill(title + "res_p_vs_p_10hits", truth_p, res_p);
503
504 histograms_.fill(title + "res_pt_beam_vs_p", truth_pt_beam,
505 res_pt_beam);
506
507 } // found matched track
508 } // do TruthComparison
509 } // loop on tracks
510
511} // 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 513 of file TrackingRecoDQM.cxx.

515 {
516 for (auto& track : tracks) {
517 // Match the tracks to truth
518 ldmx::Track* truth_trk = nullptr;
519
520 auto it = std::find_if(truth_track_collection_->begin(),
521 truth_track_collection_->end(),
522 [&](const ldmx::Track& tt) {
523 return tt.getTrackID() == track.getTrackID();
524 });
525
526 double track_truth_prob = track.getTruthProb();
527
528 if (it != truth_track_collection_->end() &&
529 track_truth_prob >= track_prob_cut_)
530 truth_trk = &(*it);
531
532 // Match not found, skip track
533 if (!truth_trk) continue;
534
535 auto trk_ts = track.getTrackState(ts_type);
536 auto truth_ts = truth_trk->getTrackState(ts_type);
537
538 if (!trk_ts.has_value()) continue;
539 if (!truth_ts.has_value()) continue;
540
541 const ldmx::Track::TrackState& target_state = trk_ts.value();
542 const ldmx::Track::TrackState& truth_target_state = truth_ts.value();
543
544 // Check that the covariance is filled
545 if (target_state.pos_mom_cov_.size() < 21) continue;
546
547 // Sigma from Cartesian position covariance (LDMX frame):
548 // pos_mom_cov_ upper-triangle layout: xx=0, yy=6
549 double sigmaloc0 = std::sqrt(target_state.pos_mom_cov_[0]); // sigma_x
550 double sigmaloc1 = std::sqrt(target_state.pos_mom_cov_[6]); // sigma_y
551
552 double trk_qop = track.getQoP();
553 double trk_p = 1000. / abs(trk_qop); // MeV
554
555 // loc0/loc1 = x/y position at the surface in LDMX global frame
556 double track_state_loc0 = target_state.pos_[0];
557 double track_state_loc1 = target_state.pos_[1];
558
559 double truth_state_loc0 = truth_target_state.pos_[0];
560 double truth_state_loc1 = truth_target_state.pos_[1];
561
562 histograms_.fill(title_ + "trk_" + ts_title + "_loc0", track_state_loc0);
563 histograms_.fill(title_ + "trk_" + ts_title + "_loc1", track_state_loc1);
564 histograms_.fill(title_ + ts_title + "_truth_loc0", truth_state_loc0);
565 histograms_.fill(title_ + ts_title + "_truth_loc1", truth_state_loc1);
566
567 // TH1F residuals
569 title_ + "trk_" + ts_title + "_loc0-truth_" + ts_title + "_loc0",
570 track_state_loc0 - truth_state_loc0);
572 title_ + "trk_" + ts_title + "_loc1-truth_" + ts_title + "_loc1",
573 track_state_loc1 - truth_state_loc1);
574
575 // TH1F The pulls of loc0 and loc1
576 histograms_.fill(title_ + ts_title + "_Pulls_of_loc0",
577 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
578 histograms_.fill(title_ + ts_title + "_Pulls_of_loc1",
579 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
580
581 // TODO:: TH1F The pulls of phi, theta, qop
582
583 // TH2F residual vs Nhits
584 histograms_.fill(title_ + ts_title + "_res_loc0-vs-N_hits",
585 track.getNhits(), track_state_loc0 - truth_state_loc0);
586 histograms_.fill(title_ + ts_title + "_res_loc1-vs-N_hits",
587 track.getNhits(), track_state_loc1 - truth_state_loc1);
588
589 // TH2F pulls vs Nhits
590 histograms_.fill(title_ + ts_title + "_pulls_loc0-vs-N_hits",
591 track.getNhits(),
592 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
593 histograms_.fill(title_ + ts_title + "_pulls_loc1-vs-N_hits",
594 track.getNhits(),
595 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
596
597 // TH2F residual vs trk_p
598 histograms_.fill(title_ + ts_title + "_res_loc0-vs-trk_p", trk_p,
599 track_state_loc0 - truth_state_loc0);
600 histograms_.fill(title_ + ts_title + "_res_loc1-vs-trk_p", trk_p,
601 track_state_loc1 - truth_state_loc1);
602
603 // TH2F pulls vs trk_p
604 histograms_.fill(title_ + ts_title + "_pulls_loc0-vs-trk_p", trk_p,
605 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
606 histograms_.fill(title_ + ts_title + "_pulls_loc1-vs-trk_p", trk_p,
607 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
608
609 } // loop on tracks
610}

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 90 of file TrackingRecoDQM.h.

90{false};

◆ duplicate_tracks_

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

Definition at line 108 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 97 of file TrackingRecoDQM.h.

97{nullptr};

◆ ecal_sp_coll_name_

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

Definition at line 78 of file TrackingRecoDQM.h.

◆ ecal_sp_passname_

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

Definition at line 79 of file TrackingRecoDQM.h.

◆ fake_tracks_

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

Definition at line 110 of file TrackingRecoDQM.h.

◆ measurement_collection_

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

Definition at line 75 of file TrackingRecoDQM.h.

◆ measurement_passname_

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

Definition at line 76 of file TrackingRecoDQM.h.

◆ pidmap_

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

Definition at line 113 of file TrackingRecoDQM.h.

◆ subdetector_

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

Definition at line 89 of file TrackingRecoDQM.h.

89{"Tagger"};

◆ target_scoring_hits_

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

Definition at line 100 of file TrackingRecoDQM.h.

100 {
101 nullptr};

◆ target_sp_coll_name_

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

Definition at line 80 of file TrackingRecoDQM.h.

◆ target_sp_passname_

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

Definition at line 81 of file TrackingRecoDQM.h.

◆ title_

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

Definition at line 87 of file TrackingRecoDQM.h.

87{"tagger_trk_"};

◆ track_collection_

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

Definition at line 73 of file TrackingRecoDQM.h.

◆ track_collection_events_passname_

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

Definition at line 82 of file TrackingRecoDQM.h.

◆ track_passname_

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

Definition at line 83 of file TrackingRecoDQM.h.

◆ track_prob_cut_

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

Definition at line 88 of file TrackingRecoDQM.h.

88{0.5};

◆ track_states_

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

Definition at line 91 of file TrackingRecoDQM.h.

◆ truth_collection_

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

Definition at line 74 of file TrackingRecoDQM.h.

◆ truth_events_passname_

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

Definition at line 84 of file TrackingRecoDQM.h.

◆ truth_passname_

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

Definition at line 85 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 94 of file TrackingRecoDQM.h.

94{nullptr};

◆ unique_tracks_

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

Definition at line 106 of file TrackingRecoDQM.h.


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