1#include "Tracking/dqm/TrackingRecoDQM.h"
6#include "Tracking/Sim/TrackingUtils.h"
8namespace tracking::dqm {
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");
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");
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", {});
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;
43 ldmx_log(trace) <<
"DQM Reading in:" << track_collection_;
45 if (!event.
exists(track_collection_, track_collection_events_passname_)) {
46 ldmx_log(error) <<
"TrackCollection " << track_collection_
47 <<
" with pass = " << track_collection_events_passname_
53 event.getCollection<
ldmx::Track>(track_collection_, track_passname_)};
55 if (!event.
exists(measurement_collection_, measurement_passname_)) {
56 ldmx_log(error) <<
"Measurement collection " << measurement_collection_
57 <<
" with pass = " << measurement_passname_
63 measurement_collection_, measurement_passname_)};
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;
73 if (event.
exists(ecal_sp_coll_name_, ecal_sp_passname_)) {
74 ecal_scoring_hits_ = std::make_shared<std::vector<ldmx::SimTrackerHit>>(
79 if (event.
exists(target_sp_coll_name_, target_sp_passname_)) {
80 target_scoring_hits_ = std::make_shared<std::vector<ldmx::SimTrackerHit>>(
82 target_sp_passname_));
85 ldmx_log(debug) <<
"Do truth comparison::" << do_truth_comparison_;
87 if (do_truth_comparison_) {
88 sortTracks(tracks, unique_tracks_, duplicate_tracks_, fake_tracks_);
90 unique_tracks_ = tracks;
93 ldmx_log(debug) <<
"Filling histograms for " << tracks.size() <<
" tracks";
98 if (!unique_tracks_.empty()) {
99 ldmx_log(debug) <<
"Track Monitoring on " << unique_tracks_.size()
101 trackMonitoring(unique_tracks_, measurements, title_,
true,
102 do_truth_comparison_);
106 if (!duplicate_tracks_.empty()) {
107 ldmx_log(debug) <<
"Track Monitoring on " << duplicate_tracks_.size()
109 trackMonitoring(duplicate_tracks_, measurements, title_ +
"dup_",
false,
112 if (!fake_tracks_.empty()) {
113 ldmx_log(debug) <<
"Track Monitoring on " << fake_tracks_.size()
115 trackMonitoring(fake_tracks_, measurements, title_ +
"fake_",
false,
false);
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()) {
127 if (std::find(track_states_.begin(), track_states_.end(),
"ecal") !=
128 track_states_.end()) {
132 if (std::find(track_states_.begin(), track_states_.end(),
"beamOrigin") !=
133 track_states_.end()) {
139 if (do_truth_comparison_) {
140 ldmx_log(trace) <<
"Technical Efficiency plots";
141 efficiencyPlots(tracks, measurements, title_);
147 ldmx_log(trace) <<
"Clear the vectors";
148 unique_tracks_.clear();
149 duplicate_tracks_.clear();
150 fake_tracks_.clear();
157void TrackingRecoDQM::efficiencyPlots(
158 const std::vector<ldmx::Track>& tracks,
159 const std::vector<ldmx::Measurement>& measurements,
160 const std::string& title) {
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());
171 auto truth_n_hits = truth_trk.getNhits();
173 auto truth_mom = truth_trk.getMomentumAtTarget();
174 double truth_pt_beam{0.}, truth_beam_angle{0.};
175 if (truth_mom.size() == 3) {
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]);
190 if (pidmap_.count(truth_trk.getPdgID()) != 0) {
195 if (pidmap_[truth_trk.getPdgID()] == PIDBins::kminus) {
199 if (pidmap_[truth_trk.getPdgID()] == PIDBins::kplus) {
203 if (pidmap_[truth_trk.getPdgID()] == PIDBins::piminus) {
207 if (pidmap_[truth_trk.getPdgID()] == PIDBins::piplus) {
211 if (pidmap_[truth_trk.getPdgID()] == PIDBins::electron) {
215 if (pidmap_[truth_trk.getPdgID()] == PIDBins::positron) {
219 if (pidmap_[truth_trk.getPdgID()] == PIDBins::proton) {
226 for (
auto& track : tracks) {
230 auto it = std::find_if(truth_track_collection_->begin(),
231 truth_track_collection_->end(),
233 return tt.getTrackID() == track.getTrackID();
236 double track_truth_prob = track.getTruthProb();
238 if (it != truth_track_collection_->end() &&
239 track_truth_prob >= track_prob_cut_)
243 if (!truth_trk)
continue;
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());
253 double truth_pt_beam{0.}, truth_beam_angle{0.};
254 if (truth_mom.size() == 3) {
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]);
270 auto dedx_measurements = track.getDedxMeasurements();
271 auto measurement_idxs = track.getMeasurementsIdxs();
272 for (
size_t i = 0; i < measurement_idxs.size(); ++i) {
274 measurements.at(measurement_idxs[i]).getLayer());
276 if (i < dedx_measurements.size()) {
278 dedx_measurements[i]);
284 if (pidmap_.count(truth_trk->getPdgID()) != 0) {
289 if (pidmap_[truth_trk->getPdgID()] == PIDBins::kminus) {
293 if (pidmap_[truth_trk->getPdgID()] == PIDBins::kplus) {
297 if (pidmap_[truth_trk->getPdgID()] == PIDBins::piminus) {
301 if (pidmap_[truth_trk->getPdgID()] == PIDBins::piplus) {
305 if (pidmap_[truth_trk->getPdgID()] == PIDBins::electron) {
309 if (pidmap_[truth_trk->getPdgID()] == PIDBins::positron) {
313 if (pidmap_[truth_trk->getPdgID()] == PIDBins::proton) {
321void TrackingRecoDQM::trackMonitoring(
322 const std::vector<ldmx::Track>& tracks,
323 const std::vector<ldmx::Measurement>& measurements,
const std::string title,
324 const bool& doDetail,
const bool& doTruth) {
325 for (
auto& track : tracks) {
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);
333 auto dedx_measurements = track.getDedxMeasurements();
334 auto measurement_idxs = track.getMeasurementsIdxs();
335 for (
size_t i = 0; i < measurement_idxs.size(); ++i) {
337 measurements.at(measurement_idxs[i]).getLayer());
339 if (i < dedx_measurements.size()) {
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];
364 if (denom <= 0.f)
continue;
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);
375 auto trk_mom = track.getMomentumAtTarget();
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];
381 py_ldmx = trk_mom[1];
382 pz_ldmx = trk_mom[2];
384 pt_bending = std::sqrt(px_ldmx * px_ldmx + pz_ldmx * pz_ldmx);
386 pt_beam = std::sqrt(px_ldmx * px_ldmx + py_ldmx * py_ldmx);
390 Acts::BoundMatrix cov =
391 tracking::sim::utils::unpackCov(track.getPerigeeCov());
393 double sigmad0 = sqrt(
394 cov(Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc0));
395 double sigmaz0 = sqrt(
396 cov(Acts::BoundIndices::eBoundLoc1, Acts::BoundIndices::eBoundLoc1));
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));
404 (1000. / trk_qop) * (1000. / trk_qop) * sigmaqop / 1000.;
425 track.getChi2() / track.getNdf());
440 if (track.getNhits() == 8)
442 else if (track.getNhits() == 9)
444 else if (track.getNhits() == 10)
452 auto it = std::find_if(truth_track_collection_->begin(),
453 truth_track_collection_->end(),
455 return tt.getTrackID() == track.getTrackID();
458 double track_truth_prob = track.getTruthProb();
460 if (it != truth_track_collection_->end() &&
461 track_truth_prob >= track_prob_cut_)
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());
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]);
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;
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;
533 if (track.getNhits() == 8)
535 else if (track.getNhits() == 9)
537 else if (track.getNhits() == 10)
550 const std::vector<ldmx::Track>& tracks, ldmx::TrackStateType ts_type,
551 const std::string& ts_title) {
552 for (
auto& track : tracks) {
556 auto it = std::find_if(truth_track_collection_->begin(),
557 truth_track_collection_->end(),
559 return tt.getTrackID() == track.getTrackID();
562 double track_truth_prob = track.getTruthProb();
564 if (it != truth_track_collection_->end() &&
565 track_truth_prob >= track_prob_cut_)
569 if (!truth_trk)
continue;
571 auto trk_ts = track.getTrackState(ts_type);
572 auto truth_ts = truth_trk->getTrackState(ts_type);
574 if (!trk_ts.has_value())
continue;
575 if (!truth_ts.has_value())
continue;
581 if (target_state.pos_mom_cov_.size() < 21)
continue;
585 double sigmaloc0 = std::sqrt(target_state.pos_mom_cov_[0]);
586 double sigmaloc1 = std::sqrt(target_state.pos_mom_cov_[6]);
588 double trk_qop = track.getQoP();
589 double trk_p = 1000. / abs(trk_qop);
592 double track_state_loc0 = target_state.pos_[0];
593 double track_state_loc1 = target_state.pos_[1];
595 double truth_state_loc0 = truth_target_state.pos_[0];
596 double truth_state_loc1 = truth_target_state.pos_[1];
598 histograms_.
fill(title_ +
"trk_" + ts_title +
"_loc0", track_state_loc0);
599 histograms_.
fill(title_ +
"trk_" + ts_title +
"_loc1", track_state_loc1);
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);
613 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
615 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
621 track.getNhits(), track_state_loc0 - truth_state_loc0);
623 track.getNhits(), track_state_loc1 - truth_state_loc1);
628 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
631 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
635 track_state_loc0 - truth_state_loc0);
637 track_state_loc1 - truth_state_loc1);
641 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
643 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
648void TrackingRecoDQM::sortTracks(
const std::vector<ldmx::Track>& tracks,
649 std::vector<ldmx::Track>& uniqueTracks,
650 std::vector<ldmx::Track>& duplicateTracks,
651 std::vector<ldmx::Track>& fakeTracks) {
653 std::vector<ldmx::Track> sorted_tracks = tracks;
656 std::sort(sorted_tracks.begin(), sorted_tracks.end(),
658 return t1.getTrackID() < t2.getTrackID();
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]);
668 if (uniqueTracks.size() == 0 ||
669 sorted_tracks[i].getTrackID() != sorted_tracks[i - 1].getTrackID()) {
670 uniqueTracks.push_back(sorted_tracks[i]);
676 else if (sorted_tracks[i].getTruthProb() >
677 uniqueTracks.back().getTruthProb()) {
678 duplicateTracks.push_back(uniqueTracks.back());
679 uniqueTracks.back() = sorted_tracks[i];
683 duplicateTracks.push_back(sorted_tracks[i]);
690 if (uniqueTracks.size() + duplicateTracks.size() + fakeTracks.size() !=
692 std::cerr <<
"Error: unique and duplicate tracks vectors do not add up to "
693 "original tracks vector";
698 ldmx_log(trace) <<
"Unique tracks:";
700 ldmx_log(trace) <<
"\tTrack ID: " << track.getTrackID()
701 <<
", Truth Prob: " << track.getTruthProb();
703 ldmx_log(trace) <<
"Duplicate tracks:";
705 ldmx_log(trace) <<
"\tTrack ID: " << track.getTrackID()
706 <<
", Truth Prob: " << track.getTruthProb();
708 ldmx_log(trace) <<
"Fake tracks:";
710 ldmx_log(trace) <<
"\tTrack ID: " << track.getTrackID()
711 <<
", Truth Prob: " << track.getTruthProb();
#define DECLARE_ANALYZER(CLASS)
Macro which allows the framework to construct an analyzer given its name during configuration.
HistogramPool histograms_
helper object for making and filling histograms
Implements an event buffer system for storing event data.
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.
void fill(const std::string &name, const T &val)
Fill a 1D histogram.
Class encapsulating parameters for configuring a processor.
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Represents a simulated tracker hit in the simulation.
Implementation of a track object.
std::vector< double > getMomentumAtTarget() const
Returns the momentum (px, py, pz) in MeV in the LDMX global frame from the AtTarget TrackState.
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 onProcessEnd() override
Callback for the EventProcessor to take any necessary action when the processing of events finishes,...
void configure(framework::config::Parameters ¶meters) override
Configure the analyzer using the given user specified parameters.
void analyze(const framework::Event &event) override
Process the event and make histograms or summaries.