1#include "Tracking/dqm/TrackingRecoDQM.h"
6#include "Tracking/Sim/TrackingUtils.h"
8namespace tracking::dqm {
12 parameters.
getParameter<std::string>(
"track_collection",
"TaggerTracks");
13 truthCollection_ = parameters.
getParameter<std::string>(
"truth_collection",
15 title_ = parameters.
getParameter<std::string>(
"title",
"tagger_trk_");
16 trackProb_cut_ = parameters.
getParameter<
double>(
"trackProb_cut", 0.5);
17 subdetector_ = parameters.
getParameter<std::string>(
"subdetector",
"Tagger");
19 parameters.
getParameter<std::vector<std::string>>(
"trackStates", {});
20 measurementCollection_ = parameters.
getParameter<std::string>(
21 "measurement_collection",
"DigiTaggerSimHits");
23 ldmx_log(info) <<
"Track Collection " << trackCollection_ << std::endl;
24 ldmx_log(info) <<
"Truth Collection " << truthCollection_ << std::endl;
26 pidmap[-321] = PIDBins::kminus;
27 pidmap[321] = PIDBins::kplus;
28 pidmap[-211] = PIDBins::piminus;
29 pidmap[211] = PIDBins::piplus;
30 pidmap[11] = PIDBins::electron;
31 pidmap[-11] = PIDBins::positron;
32 pidmap[2212] = PIDBins::proton;
33 pidmap[-2212] = PIDBins::antiproton;
37 ldmx_log(debug) <<
"DQM Reading in::" << trackCollection_ << std::endl;
39 if (!event.
exists(trackCollection_)) {
40 ldmx_log(error) <<
"ERROR:: trackCollection " << trackCollection_
41 <<
" not in event" << std::endl;
44 auto tracks{
event.getCollection<
ldmx::Track>(trackCollection_)};
48 if (event.
exists(truthCollection_)) {
49 truthTrackCollection_ = std::make_shared<ldmx::Tracks>(
51 doTruthComparison =
true;
55 if (event.
exists(
"EcalScoringPlaneHits")) {
56 ecal_scoring_hits_ = std::make_shared<std::vector<ldmx::SimTrackerHit>>(
60 if (event.
exists(
"TargetScoringPlaneHits")) {
61 target_scoring_hits_ = std::make_shared<std::vector<ldmx::SimTrackerHit>>(
65 ldmx_log(debug) <<
"Do truth comparison::" << doTruthComparison << std::endl;
67 if (doTruthComparison) {
68 sortTracks(tracks, uniqueTracks_, duplicateTracks_, fakeTracks_);
70 uniqueTracks_ = tracks;
73 ldmx_log(debug) <<
"Filling histograms " << std::endl;
78 ldmx_log(debug) <<
"Track Monitoring on Unique Tracks" << std::endl;
80 TrackMonitoring(uniqueTracks_, measurements, title_,
true,
true);
82 ldmx_log(debug) <<
"Track Monitoring on duplicates and fakes" << std::endl;
84 TrackMonitoring(duplicateTracks_, measurements, title_ +
"dup_",
false,
86 TrackMonitoring(fakeTracks_, measurements, title_ +
"fake_",
false,
false);
90 if (std::find(trackStates_.begin(), trackStates_.end(),
"target") !=
95 if (std::find(trackStates_.begin(), trackStates_.end(),
"ecal") !=
100 if (std::find(trackStates_.begin(), trackStates_.end(),
"beamOrigin") !=
101 trackStates_.end()) {
107 EfficiencyPlots(tracks, measurements, title_);
112 uniqueTracks_.clear();
113 duplicateTracks_.clear();
121void TrackingRecoDQM::EfficiencyPlots(
122 const std::vector<ldmx::Track>& tracks,
123 const std::vector<ldmx::Measurement>& measurements,
124 const std::string& title) {
127 histograms_.
fill(title +
"truth_N_tracks", truthTrackCollection_->size());
128 for (
auto& truth_trk : *(truthTrackCollection_)) {
129 double truth_phi = truth_trk.getPhi();
130 double truth_d0 = truth_trk.getD0();
131 double truth_z0 = truth_trk.getZ0();
132 double truth_theta = truth_trk.getTheta();
133 double truth_qop = truth_trk.getQoP();
134 double truth_p = 1. / abs(truth_trk.getQoP());
135 int truth_nHits = truth_trk.getNhits();
137 std::vector<double> truth_mom = truth_trk.getMomentum();
141 double truth_pt_beam =
142 std::sqrt(truth_mom[1] * truth_mom[1] + truth_mom[2] * truth_mom[2]);
144 double truth_beam_angle = std::atan2(truth_pt_beam, truth_mom[0]);
155 if (pidmap.count(truth_trk.getPdgID()) != 0) {
160 if (pidmap[truth_trk.getPdgID()] == PIDBins::kminus) {
164 if (pidmap[truth_trk.getPdgID()] == PIDBins::kplus) {
168 if (pidmap[truth_trk.getPdgID()] == PIDBins::piminus) {
172 if (pidmap[truth_trk.getPdgID()] == PIDBins::piplus) {
176 if (pidmap[truth_trk.getPdgID()] == PIDBins::electron) {
180 if (pidmap[truth_trk.getPdgID()] == PIDBins::positron) {
184 if (pidmap[truth_trk.getPdgID()] == PIDBins::proton) {
191 for (
auto& track : tracks) {
196 std::find_if(truthTrackCollection_->begin(),
197 truthTrackCollection_->end(), [&](
const ldmx::Track& tt) {
198 return tt.getTrackID() == track.getTrackID();
201 double trackTruthProb = track.getTruthProb();
203 if (it != truthTrackCollection_->end() && trackTruthProb >= trackProb_cut_)
207 if (!truth_trk)
return;
209 double truth_phi = truth_trk->getPhi();
210 double truth_d0 = truth_trk->getD0();
211 double truth_z0 = truth_trk->getZ0();
212 double truth_theta = truth_trk->getTheta();
213 double truth_qop = truth_trk->getQoP();
214 double truth_p = 1. / abs(truth_trk->getQoP());
215 std::vector<double> truth_mom = truth_trk->getMomentum();
219 double truth_pt_beam =
220 std::sqrt(truth_mom[1] * truth_mom[1] + truth_mom[2] * truth_mom[2]);
222 double truth_beam_angle = std::atan2(truth_pt_beam, truth_mom[0]);
234 for (
auto trackHit : track.getMeasurementsIdxs()) {
236 measurements.at(trackHit).getLayer());
241 if (pidmap.count(truth_trk->getPdgID()) != 0) {
246 if (pidmap[truth_trk->getPdgID()] == PIDBins::kminus) {
250 if (pidmap[truth_trk->getPdgID()] == PIDBins::kplus) {
254 if (pidmap[truth_trk->getPdgID()] == PIDBins::piminus) {
258 if (pidmap[truth_trk->getPdgID()] == PIDBins::piplus) {
262 if (pidmap[truth_trk->getPdgID()] == PIDBins::electron) {
266 if (pidmap[truth_trk->getPdgID()] == PIDBins::positron) {
270 if (pidmap[truth_trk->getPdgID()] == PIDBins::proton) {
278void TrackingRecoDQM::TrackMonitoring(
279 const std::vector<ldmx::Track>& tracks,
280 const std::vector<ldmx::Measurement>& measurements,
const std::string title,
281 const bool& doDetail,
const bool& doTruth) {
282 for (
auto& track : tracks) {
284 double trk_d0 = track.getD0();
285 double trk_z0 = track.getZ0();
286 double trk_qop = track.getQoP();
287 double trk_theta = track.getTheta();
288 double trk_phi = track.getPhi();
289 double trk_p = 1. / abs(trk_qop);
290 for (
auto trackHit : track.getMeasurementsIdxs()) {
292 measurements.at(trackHit).getLayer());
295 std::vector<double> trk_mom = track.getMomentum();
299 std::sqrt(trk_mom[0] * trk_mom[0] + trk_mom[1] * trk_mom[1]);
303 std::sqrt(trk_mom[1] * trk_mom[1] + trk_mom[2] * trk_mom[2]);
306 Acts::BoundSquareMatrix cov =
307 tracking::sim::utils::unpackCov(track.getPerigeeCov());
309 double sigmad0 = sqrt(
310 cov(Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc0));
311 double sigmaz0 = sqrt(
312 cov(Acts::BoundIndices::eBoundLoc1, Acts::BoundIndices::eBoundLoc1));
314 sqrt(cov(Acts::BoundIndices::eBoundPhi, Acts::BoundIndices::eBoundPhi));
315 double sigmatheta = sqrt(
316 cov(Acts::BoundIndices::eBoundTheta, Acts::BoundIndices::eBoundTheta));
317 double sigmaqop = sqrt(cov(Acts::BoundIndices::eBoundQOverP,
318 Acts::BoundIndices::eBoundQOverP));
319 double sigmap = (1. / trk_qop) * (1. / trk_qop) * sigmaqop;
340 track.getChi2() / track.getNdf());
352 double p = std::abs(1. / trk_qop);
354 histograms_.
fill(title +
"z0_err_vs_p", std::abs(1. / trk_qop), sigmaz0);
355 histograms_.
fill(title +
"p_err_vs_p", std::abs(1. / trk_qop), sigmap);
357 if (track.getNhits() == 8)
359 else if (track.getNhits() == 9)
361 else if (track.getNhits() == 10)
369 auto it = std::find_if(truthTrackCollection_->begin(),
370 truthTrackCollection_->end(),
372 return tt.getTrackID() == track.getTrackID();
375 double trackTruthProb = track.getTruthProb();
377 if (it != truthTrackCollection_->end() &&
378 trackTruthProb >= trackProb_cut_)
383 double truth_d0 = truth_trk->getD0();
384 double truth_z0 = truth_trk->getZ0();
385 double truth_phi = truth_trk->getPhi();
386 double truth_theta = truth_trk->getTheta();
387 double truth_qop = truth_trk->getQoP();
388 double truth_p = 1. / abs(truth_trk->getQoP());
389 std::vector<double> truth_mom = truth_trk->getMomentum();
392 double truth_pt_beam = std::sqrt(truth_mom[1] * truth_mom[1] +
393 truth_mom[2] * truth_mom[2]);
402 double res_d0 = trk_d0 - truth_d0;
403 double res_z0 = trk_z0 - truth_z0;
404 double res_phi = trk_phi - truth_phi;
405 double res_theta = trk_theta - truth_theta;
406 double res_qop = trk_qop - truth_qop;
407 double res_p = trk_p - truth_p;
408 double res_pt_beam = pt_beam - truth_pt_beam;
418 double pull_d0 = res_d0 / sigmad0;
419 double pull_z0 = res_z0 / sigmaz0;
420 double pull_phi = res_phi / sigmaphi;
421 double pull_theta = res_theta / sigmatheta;
422 double pull_qop = res_qop / sigmaqop;
423 double pull_p = res_p / sigmap;
448 if (track.getNhits() == 8)
450 else if (track.getNhits() == 9)
452 else if (track.getNhits() == 10)
465 ldmx::TrackStateType ts_type,
466 const std::string& ts_title) {
467 for (
auto& track : tracks) {
472 std::find_if(truthTrackCollection_->begin(),
473 truthTrackCollection_->end(), [&](
const ldmx::Track& tt) {
474 return tt.getTrackID() == track.getTrackID();
477 double trackTruthProb = track.getTruthProb();
479 if (it != truthTrackCollection_->end() && trackTruthProb >= trackProb_cut_)
483 if (!truth_trk)
continue;
487 auto trk_ts = track.getTrackState(ts_type);
488 auto truth_ts = truth_trk->getTrackState(ts_type);
490 if (!trk_ts.has_value())
continue;
492 if (!truth_ts.has_value())
continue;
497 ldmx_log(debug) <<
"Unpacking covariance matrix" << std::endl;
498 Acts::BoundSquareMatrix cov =
499 tracking::sim::utils::unpackCov(TargetState.cov);
501 [[maybe_unused]]
double sigmaloc0 = sqrt(
502 cov(Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc0));
503 [[maybe_unused]]
double sigmaloc1 = sqrt(
504 cov(Acts::BoundIndices::eBoundLoc1, Acts::BoundIndices::eBoundLoc1));
505 [[maybe_unused]]
double sigmaphi =
506 sqrt(cov(Acts::BoundIndices::eBoundPhi, Acts::BoundIndices::eBoundPhi));
507 [[maybe_unused]]
double sigmatheta = sqrt(
508 cov(Acts::BoundIndices::eBoundTheta, Acts::BoundIndices::eBoundTheta));
509 [[maybe_unused]]
double sigmaqop = sqrt(cov(
510 Acts::BoundIndices::eBoundQOverP, Acts::BoundIndices::eBoundQOverP));
512 double trk_qop = track.getQoP();
513 double trk_p = 1. / abs(trk_qop);
515 double track_state_loc0 = TargetState.params[0];
516 double track_state_loc1 = TargetState.params[1];
517 [[maybe_unused]]
double track_state_phi = TargetState.params[2];
518 [[maybe_unused]]
double track_state_theta = TargetState.params[3];
519 [[maybe_unused]]
double track_state_p = TargetState.params[4];
521 double truth_state_loc0 = truthTargetState.params[0];
522 double truth_state_loc1 = truthTargetState.params[1];
523 [[maybe_unused]]
double truth_state_phi = truthTargetState.params[2];
524 [[maybe_unused]]
double truth_state_theta = truthTargetState.params[3];
525 [[maybe_unused]]
double truth_state_p = truthTargetState.params[4];
528 if (TargetState.params.size() < 5)
continue;
530 histograms_.
fill(title_ +
"trk_" + ts_title +
"_loc0", track_state_loc0);
531 histograms_.
fill(title_ +
"trk_" + ts_title +
"_loc1", track_state_loc1);
537 track_state_loc0 - truth_state_loc0);
539 track_state_loc1 - truth_state_loc1);
543 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
545 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
551 track.getNhits(), track_state_loc0 - truth_state_loc0);
553 track.getNhits(), track_state_loc1 - truth_state_loc1);
558 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
561 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
565 track_state_loc0 - truth_state_loc0);
567 track_state_loc1 - truth_state_loc1);
571 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
573 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
578void TrackingRecoDQM::sortTracks(
const std::vector<ldmx::Track>& tracks,
579 std::vector<ldmx::Track>& uniqueTracks,
580 std::vector<ldmx::Track>& duplicateTracks,
581 std::vector<ldmx::Track>& fakeTracks) {
583 std::vector<ldmx::Track> sortedTracks = tracks;
586 std::sort(sortedTracks.begin(), sortedTracks.end(),
588 return t1.getTrackID() < t2.getTrackID();
592 for (
size_t i = 0; i < sortedTracks.size(); i++) {
593 if (sortedTracks[i].getTruthProb() < trackProb_cut_)
594 fakeTracks.push_back(sortedTracks[i]);
598 if (uniqueTracks.size() == 0 ||
599 sortedTracks[i].getTrackID() != sortedTracks[i - 1].getTrackID()) {
600 uniqueTracks.push_back(sortedTracks[i]);
606 else if (sortedTracks[i].getTruthProb() >
607 uniqueTracks.back().getTruthProb()) {
608 duplicateTracks.push_back(uniqueTracks.back());
609 uniqueTracks.back() = sortedTracks[i];
613 duplicateTracks.push_back(sortedTracks[i]);
620 if (uniqueTracks.size() + duplicateTracks.size() + fakeTracks.size() !=
622 std::cerr <<
"Error: unique and duplicate tracks vectors do not add up to "
623 "original tracks vector"
630 std::cout <<
"Unique tracks:" << std::endl;
632 std::cout <<
"Track ID: " << track.getTrackID()
633 <<
", Truth Prob: " << track.getTruthProb() << std::endl;
635 std::cout <<
"Duplicate tracks:" << std::endl;
637 std::cout <<
"Track ID: " << track.getTrackID()
638 <<
", Truth Prob: " << track.getTruthProb() << std::endl;
640 std::cout <<
"Fake tracks:" << std::endl;
642 std::cout <<
"Track ID: " << track.getTrackID()
643 <<
", Truth Prob: " << track.getTruthProb() << std::endl;
#define DECLARE_ANALYZER_NS(NS, CLASS)
Macro which allows the framework to construct an analyzer given its name during configuration.
HistogramHelper histograms_
Interface class for making and filling histograms.
Implements an event buffer system for storing event data.
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.
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 double &val)
Fill a 1D histogram.
Class encapsulating parameters for configuring a processor.
T getParameter(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 TrackStateMonitoring(const ldmx::Tracks &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.