1#include "Tracking/dqm/TrackingRecoDQM.h"
3namespace tracking::dqm {
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");
12 ecal_sp_events_passname_ =
13 parameters.
get<std::string>(
"ecal_sp_events_passname");
14 ecal_sp_passname_ = parameters.
get<std::string>(
"ecal_sp_passname");
15 target_sp_events_passname_ =
16 parameters.
get<std::string>(
"target_sp_events_passname");
17 target_sp_passname_ = parameters.
get<std::string>(
"target_sp_passname");
18 truth_passname_ = parameters.
get<std::string>(
"truth_passname");
19 truth_events_passname_ = parameters.
get<std::string>(
"truth_events_passname");
20 track_passname_ = parameters.
get<std::string>(
"track_passname");
21 track_collection_events_passname_ =
22 parameters.
get<std::string>(
"track_collection_events_passname");
24 title_ = parameters.
get<std::string>(
"title",
"tagger_trk_");
25 track_prob_cut_ = parameters.
get<
double>(
"trackProb_cut", 0.5);
26 subdetector_ = parameters.
get<std::string>(
"subdetector",
"Tagger");
27 track_states_ = parameters.
get<std::vector<std::string>>(
"trackStates", {});
29 pidmap_[-321] = PIDBins::kminus;
30 pidmap_[321] = PIDBins::kplus;
31 pidmap_[-211] = PIDBins::piminus;
32 pidmap_[211] = PIDBins::piplus;
33 pidmap_[11] = PIDBins::electron;
34 pidmap_[-11] = PIDBins::positron;
35 pidmap_[2212] = PIDBins::proton;
36 pidmap_[-2212] = PIDBins::antiproton;
40 ldmx_log(trace) <<
"DQM Reading in:" << track_collection_;
42 if (!event.
exists(track_collection_, track_collection_events_passname_)) {
43 ldmx_log(error) <<
"TrackCollection " << track_collection_
44 <<
" with pass = " << track_collection_events_passname_
50 event.getCollection<
ldmx::Track>(track_collection_, track_passname_)};
52 measurement_collection_, measurement_passname_)};
55 if (event.
exists(truth_collection_, truth_events_passname_)) {
56 truth_track_collection_ = std::make_shared<ldmx::Tracks>(
58 do_truth_comparison_ =
true;
62 if (event.
exists(
"EcalScoringPlaneHits", ecal_sp_events_passname_)) {
63 ecal_scoring_hits_ = std::make_shared<std::vector<ldmx::SimTrackerHit>>(
68 if (event.
exists(
"TargetScoringPlaneHits", target_sp_events_passname_)) {
69 target_scoring_hits_ = std::make_shared<std::vector<ldmx::SimTrackerHit>>(
71 target_sp_passname_));
74 ldmx_log(debug) <<
"Do truth comparison::" << do_truth_comparison_;
76 if (do_truth_comparison_) {
77 sortTracks(tracks, unique_tracks_, duplicate_tracks_, fake_tracks_);
79 unique_tracks_ = tracks;
82 ldmx_log(debug) <<
"Filling histograms for " << tracks.size() <<
" tracks";
87 if (!unique_tracks_.empty()) {
88 ldmx_log(debug) <<
"Track Monitoring on " << unique_tracks_.size()
90 trackMonitoring(unique_tracks_, measurements, title_,
true,
91 do_truth_comparison_);
95 if (!duplicate_tracks_.empty()) {
96 ldmx_log(debug) <<
"Track Monitoring on " << duplicate_tracks_.size()
98 trackMonitoring(duplicate_tracks_, measurements, title_ +
"dup_",
false,
101 if (!fake_tracks_.empty()) {
102 ldmx_log(debug) <<
"Track Monitoring on " << fake_tracks_.size()
104 trackMonitoring(fake_tracks_, measurements, title_ +
"fake_",
false,
false);
108 ldmx_log(trace) <<
"Track Extrapolation to Ecal Monitoring";
109 if (std::find(track_states_.begin(), track_states_.end(),
"target") !=
110 track_states_.end()) {
114 if (std::find(track_states_.begin(), track_states_.end(),
"ecal") !=
115 track_states_.end()) {
119 if (std::find(track_states_.begin(), track_states_.end(),
"beamOrigin") !=
120 track_states_.end()) {
126 if (do_truth_comparison_) {
127 ldmx_log(trace) <<
"Technical Efficiency plots";
128 efficiencyPlots(tracks, measurements, title_);
134 ldmx_log(trace) <<
"Clear the vectors";
135 unique_tracks_.clear();
136 duplicate_tracks_.clear();
137 fake_tracks_.clear();
144void TrackingRecoDQM::efficiencyPlots(
145 const std::vector<ldmx::Track>& tracks,
146 const std::vector<ldmx::Measurement>& measurements,
147 const std::string& title) {
150 histograms_.
fill(title +
"truth_N_tracks", truth_track_collection_->size());
151 for (
auto& truth_trk : *(truth_track_collection_)) {
152 auto truth_phi = truth_trk.getPhi();
153 auto truth_d0 = truth_trk.getD0();
154 auto truth_z0 = truth_trk.getZ0();
155 auto truth_theta = truth_trk.getTheta();
156 auto truth_qop = truth_trk.getQoP();
157 auto truth_p = 1. / abs(truth_trk.getQoP());
158 auto truth_n_hits = truth_trk.getNhits();
160 std::vector<double> truth_mom = truth_trk.getMomentum();
165 std::sqrt(truth_mom[1] * truth_mom[1] + truth_mom[2] * truth_mom[2]);
167 auto truth_beam_angle = std::atan2(truth_pt_beam, truth_mom[0]);
178 if (pidmap_.count(truth_trk.getPdgID()) != 0) {
183 if (pidmap_[truth_trk.getPdgID()] == PIDBins::kminus) {
187 if (pidmap_[truth_trk.getPdgID()] == PIDBins::kplus) {
191 if (pidmap_[truth_trk.getPdgID()] == PIDBins::piminus) {
195 if (pidmap_[truth_trk.getPdgID()] == PIDBins::piplus) {
199 if (pidmap_[truth_trk.getPdgID()] == PIDBins::electron) {
203 if (pidmap_[truth_trk.getPdgID()] == PIDBins::positron) {
207 if (pidmap_[truth_trk.getPdgID()] == PIDBins::proton) {
214 for (
auto& track : tracks) {
218 auto it = std::find_if(truth_track_collection_->begin(),
219 truth_track_collection_->end(),
221 return tt.getTrackID() == track.getTrackID();
224 double track_truth_prob = track.getTruthProb();
226 if (it != truth_track_collection_->end() &&
227 track_truth_prob >= track_prob_cut_)
231 if (!truth_trk)
return;
233 auto truth_phi = truth_trk->getPhi();
234 auto truth_d0 = truth_trk->getD0();
235 auto truth_z0 = truth_trk->getZ0();
236 auto truth_theta = truth_trk->getTheta();
237 auto truth_qop = truth_trk->getQoP();
238 auto truth_p = 1. / abs(truth_trk->getQoP());
239 std::vector<double> truth_mom = truth_trk->getMomentum();
244 std::sqrt(truth_mom[1] * truth_mom[1] + truth_mom[2] * truth_mom[2]);
246 auto truth_beam_angle = std::atan2(truth_pt_beam, truth_mom[0]);
258 for (
auto track_hit : track.getMeasurementsIdxs()) {
260 measurements.at(track_hit).getLayer());
265 if (pidmap_.count(truth_trk->getPdgID()) != 0) {
270 if (pidmap_[truth_trk->getPdgID()] == PIDBins::kminus) {
274 if (pidmap_[truth_trk->getPdgID()] == PIDBins::kplus) {
278 if (pidmap_[truth_trk->getPdgID()] == PIDBins::piminus) {
282 if (pidmap_[truth_trk->getPdgID()] == PIDBins::piplus) {
286 if (pidmap_[truth_trk->getPdgID()] == PIDBins::electron) {
290 if (pidmap_[truth_trk->getPdgID()] == PIDBins::positron) {
294 if (pidmap_[truth_trk->getPdgID()] == PIDBins::proton) {
302void TrackingRecoDQM::trackMonitoring(
303 const std::vector<ldmx::Track>& tracks,
304 const std::vector<ldmx::Measurement>& measurements,
const std::string title,
305 const bool& doDetail,
const bool& doTruth) {
306 for (
auto& track : tracks) {
308 auto trk_d0 = track.getD0();
309 auto trk_z0 = track.getZ0();
310 auto trk_qop = track.getQoP();
311 auto trk_theta = track.getTheta();
312 auto trk_phi = track.getPhi();
313 auto trk_p = 1. / abs(trk_qop);
314 for (
auto track_hit : track.getMeasurementsIdxs()) {
316 measurements.at(track_hit).getLayer());
319 std::vector<double> trk_mom = track.getMomentum();
323 std::sqrt(trk_mom[0] * trk_mom[0] + trk_mom[1] * trk_mom[1]);
327 std::sqrt(trk_mom[1] * trk_mom[1] + trk_mom[2] * trk_mom[2]);
330 Acts::BoundSquareMatrix cov =
331 tracking::sim::utils::unpackCov(track.getPerigeeCov());
333 double sigmad0 = sqrt(
334 cov(Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc0));
335 double sigmaz0 = sqrt(
336 cov(Acts::BoundIndices::eBoundLoc1, Acts::BoundIndices::eBoundLoc1));
338 sqrt(cov(Acts::BoundIndices::eBoundPhi, Acts::BoundIndices::eBoundPhi));
339 double sigmatheta = sqrt(
340 cov(Acts::BoundIndices::eBoundTheta, Acts::BoundIndices::eBoundTheta));
341 double sigmaqop = sqrt(cov(Acts::BoundIndices::eBoundQOverP,
342 Acts::BoundIndices::eBoundQOverP));
343 double sigmap = (1. / trk_qop) * (1. / trk_qop) * sigmaqop;
364 track.getChi2() / track.getNdf());
375 double p = std::abs(1. / trk_qop);
377 histograms_.
fill(title +
"z0_err_vs_p", std::abs(1. / trk_qop), sigmaz0);
378 histograms_.
fill(title +
"p_err_vs_p", std::abs(1. / trk_qop), sigmap);
380 if (track.getNhits() == 8)
382 else if (track.getNhits() == 9)
384 else if (track.getNhits() == 10)
392 auto it = std::find_if(truth_track_collection_->begin(),
393 truth_track_collection_->end(),
395 return tt.getTrackID() == track.getTrackID();
398 double track_truth_prob = track.getTruthProb();
400 if (it != truth_track_collection_->end() &&
401 track_truth_prob >= track_prob_cut_)
406 auto truth_d0 = truth_trk->getD0();
407 auto truth_z0 = truth_trk->getZ0();
408 auto truth_phi = truth_trk->getPhi();
409 auto truth_theta = truth_trk->getTheta();
410 auto truth_qop = truth_trk->getQoP();
411 auto truth_p = 1. / abs(truth_trk->getQoP());
412 std::vector<double> truth_mom = truth_trk->getMomentum();
415 double truth_pt_beam = std::sqrt(truth_mom[1] * truth_mom[1] +
416 truth_mom[2] * truth_mom[2]);
425 double res_d0 = trk_d0 - truth_d0;
426 double res_z0 = trk_z0 - truth_z0;
427 double res_phi = trk_phi - truth_phi;
428 double res_theta = trk_theta - truth_theta;
429 double res_qop = trk_qop - truth_qop;
430 double res_p = trk_p - truth_p;
431 double res_pt_beam = pt_beam - truth_pt_beam;
441 double pull_d0 = res_d0 / sigmad0;
442 double pull_z0 = res_z0 / sigmaz0;
443 double pull_phi = res_phi / sigmaphi;
444 double pull_theta = res_theta / sigmatheta;
445 double pull_qop = res_qop / sigmaqop;
446 double pull_p = res_p / sigmap;
471 if (track.getNhits() == 8)
473 else if (track.getNhits() == 9)
475 else if (track.getNhits() == 10)
488 ldmx::TrackStateType ts_type,
489 const std::string& ts_title) {
490 for (
auto& track : tracks) {
494 auto it = std::find_if(truth_track_collection_->begin(),
495 truth_track_collection_->end(),
497 return tt.getTrackID() == track.getTrackID();
500 double track_truth_prob = track.getTruthProb();
502 if (it != truth_track_collection_->end() &&
503 track_truth_prob >= track_prob_cut_)
507 if (!truth_trk)
continue;
511 auto trk_ts = track.getTrackState(ts_type);
512 auto truth_ts = truth_trk->getTrackState(ts_type);
514 if (!trk_ts.has_value())
continue;
516 if (!truth_ts.has_value())
continue;
521 ldmx_log(debug) <<
"Unpacking covariance matrix";
522 Acts::BoundSquareMatrix cov =
523 tracking::sim::utils::unpackCov(target_state.cov_);
525 [[maybe_unused]]
double sigmaloc0 = sqrt(
526 cov(Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc0));
527 [[maybe_unused]]
double sigmaloc1 = sqrt(
528 cov(Acts::BoundIndices::eBoundLoc1, Acts::BoundIndices::eBoundLoc1));
529 [[maybe_unused]]
double sigmaphi =
530 sqrt(cov(Acts::BoundIndices::eBoundPhi, Acts::BoundIndices::eBoundPhi));
531 [[maybe_unused]]
double sigmatheta = sqrt(
532 cov(Acts::BoundIndices::eBoundTheta, Acts::BoundIndices::eBoundTheta));
533 [[maybe_unused]]
double sigmaqop = sqrt(cov(
534 Acts::BoundIndices::eBoundQOverP, Acts::BoundIndices::eBoundQOverP));
536 double trk_qop = track.getQoP();
537 double trk_p = 1. / abs(trk_qop);
539 double track_state_loc0 = target_state.params_[0];
540 double track_state_loc1 = target_state.params_[1];
541 [[maybe_unused]]
double track_state_phi = target_state.params_[2];
542 [[maybe_unused]]
double track_state_theta = target_state.params_[3];
543 [[maybe_unused]]
double track_state_p = target_state.params_[4];
545 double truth_state_loc0 = truth_target_state.params_[0];
546 double truth_state_loc1 = truth_target_state.params_[1];
547 [[maybe_unused]]
double truth_state_phi = truth_target_state.params_[2];
548 [[maybe_unused]]
double truth_state_theta = truth_target_state.params_[3];
549 [[maybe_unused]]
double truth_state_p = truth_target_state.params_[4];
552 if (target_state.params_.size() < 5)
continue;
554 histograms_.
fill(title_ +
"trk_" + ts_title +
"_loc0", track_state_loc0);
555 histograms_.
fill(title_ +
"trk_" + ts_title +
"_loc1", track_state_loc1);
561 track_state_loc0 - truth_state_loc0);
563 track_state_loc1 - truth_state_loc1);
567 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
569 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
575 track.getNhits(), track_state_loc0 - truth_state_loc0);
577 track.getNhits(), track_state_loc1 - truth_state_loc1);
582 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
585 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
589 track_state_loc0 - truth_state_loc0);
591 track_state_loc1 - truth_state_loc1);
595 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
597 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
602void TrackingRecoDQM::sortTracks(
const std::vector<ldmx::Track>& tracks,
603 std::vector<ldmx::Track>& uniqueTracks,
604 std::vector<ldmx::Track>& duplicateTracks,
605 std::vector<ldmx::Track>& fakeTracks) {
607 std::vector<ldmx::Track> sorted_tracks = tracks;
610 std::sort(sorted_tracks.begin(), sorted_tracks.end(),
612 return t1.getTrackID() < t2.getTrackID();
616 for (
size_t i = 0; i < sorted_tracks.size(); i++) {
617 if (sorted_tracks[i].getTruthProb() < track_prob_cut_)
618 fakeTracks.push_back(sorted_tracks[i]);
622 if (uniqueTracks.size() == 0 ||
623 sorted_tracks[i].getTrackID() != sorted_tracks[i - 1].getTrackID()) {
624 uniqueTracks.push_back(sorted_tracks[i]);
630 else if (sorted_tracks[i].getTruthProb() >
631 uniqueTracks.back().getTruthProb()) {
632 duplicateTracks.push_back(uniqueTracks.back());
633 uniqueTracks.back() = sorted_tracks[i];
637 duplicateTracks.push_back(sorted_tracks[i]);
644 if (uniqueTracks.size() + duplicateTracks.size() + fakeTracks.size() !=
646 std::cerr <<
"Error: unique and duplicate tracks vectors do not add up to "
647 "original tracks vector";
652 ldmx_log(trace) <<
"Unique tracks:";
654 ldmx_log(trace) <<
"\tTrack ID: " << track.getTrackID()
655 <<
", Truth Prob: " << track.getTruthProb();
657 ldmx_log(trace) <<
"Duplicate tracks:";
659 ldmx_log(trace) <<
"\tTrack ID: " << track.getTrackID()
660 <<
", Truth Prob: " << track.getTruthProb();
662 ldmx_log(trace) <<
"Fake tracks:";
664 ldmx_log(trace) <<
"\tTrack ID: " << track.getTrackID()
665 <<
", 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.
const std::vector< ContentType > & getCollection(const std::string &collectionName, const std::string &passName) const
Get a collection (std::vector) of objects from the event bus.
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.
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.
void trackStateMonitoring(const ldmx::Tracks &tracks, ldmx::TrackStateType ts_type, const std::string &ts_title)
Monitoring plots for tracks extrapolated to the ECAL Scoring plane.