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 sp_pass_name_ = parameters.getParameter<std::string>(
"track_collection",
"");
16 title_ = parameters.getParameter<std::string>(
"title",
"tagger_trk_");
17 trackProb_cut_ = parameters.getParameter<
double>(
"trackProb_cut", 0.5);
18 subdetector_ = parameters.getParameter<std::string>(
"subdetector",
"Tagger");
20 parameters.getParameter<std::vector<std::string>>(
"trackStates", {});
21 measurementCollection_ = parameters.getParameter<std::string>(
22 "measurement_collection",
"DigiTaggerSimHits");
24 ldmx_log(info) <<
"Track Collection " << trackCollection_ << std::endl;
25 ldmx_log(info) <<
"Truth Collection " << truthCollection_ << std::endl;
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;
38 ldmx_log(debug) <<
"DQM Reading in::" << trackCollection_ << std::endl;
40 if (!event.
exists(trackCollection_)) {
41 ldmx_log(error) <<
"ERROR:: trackCollection " << trackCollection_
42 <<
" not in event" << std::endl;
45 auto tracks{
event.getCollection<
ldmx::Track>(trackCollection_)};
49 if (event.
exists(truthCollection_)) {
50 truthTrackCollection_ = std::make_shared<ldmx::Tracks>(
52 doTruthComparison =
true;
56 if (event.
exists(
"EcalScoringPlaneHits", sp_pass_name_)) {
57 ecal_scoring_hits_ = std::make_shared<std::vector<ldmx::SimTrackerHit>>(
62 if (event.
exists(
"TargetScoringPlaneHits", sp_pass_name_)) {
63 target_scoring_hits_ = std::make_shared<std::vector<ldmx::SimTrackerHit>>(
68 ldmx_log(debug) <<
"Do truth comparison::" << doTruthComparison << std::endl;
70 if (doTruthComparison) {
71 sortTracks(tracks, uniqueTracks_, duplicateTracks_, fakeTracks_);
73 uniqueTracks_ = tracks;
76 ldmx_log(debug) <<
"Filling histograms " << std::endl;
81 ldmx_log(debug) <<
"Track Monitoring on Unique Tracks" << std::endl;
83 TrackMonitoring(uniqueTracks_, measurements, title_,
true,
true);
85 ldmx_log(debug) <<
"Track Monitoring on duplicates and fakes" << std::endl;
87 TrackMonitoring(duplicateTracks_, measurements, title_ +
"dup_",
false,
89 TrackMonitoring(fakeTracks_, measurements, title_ +
"fake_",
false,
false);
93 if (std::find(trackStates_.begin(), trackStates_.end(),
"target") !=
98 if (std::find(trackStates_.begin(), trackStates_.end(),
"ecal") !=
103 if (std::find(trackStates_.begin(), trackStates_.end(),
"beamOrigin") !=
104 trackStates_.end()) {
110 EfficiencyPlots(tracks, measurements, title_);
115 uniqueTracks_.clear();
116 duplicateTracks_.clear();
124void TrackingRecoDQM::EfficiencyPlots(
125 const std::vector<ldmx::Track>& tracks,
126 const std::vector<ldmx::Measurement>& measurements,
127 const std::string& title) {
130 histograms_.
fill(title +
"truth_N_tracks", truthTrackCollection_->size());
131 for (
auto& truth_trk : *(truthTrackCollection_)) {
132 double truth_phi = truth_trk.getPhi();
133 double truth_d0 = truth_trk.getD0();
134 double truth_z0 = truth_trk.getZ0();
135 double truth_theta = truth_trk.getTheta();
136 double truth_qop = truth_trk.getQoP();
137 double truth_p = 1. / abs(truth_trk.getQoP());
138 int truth_nHits = truth_trk.getNhits();
140 std::vector<double> truth_mom = truth_trk.getMomentum();
144 double truth_pt_beam =
145 std::sqrt(truth_mom[1] * truth_mom[1] + truth_mom[2] * truth_mom[2]);
147 double truth_beam_angle = std::atan2(truth_pt_beam, truth_mom[0]);
158 if (pidmap.count(truth_trk.getPdgID()) != 0) {
163 if (pidmap[truth_trk.getPdgID()] == PIDBins::kminus) {
167 if (pidmap[truth_trk.getPdgID()] == PIDBins::kplus) {
171 if (pidmap[truth_trk.getPdgID()] == PIDBins::piminus) {
175 if (pidmap[truth_trk.getPdgID()] == PIDBins::piplus) {
179 if (pidmap[truth_trk.getPdgID()] == PIDBins::electron) {
183 if (pidmap[truth_trk.getPdgID()] == PIDBins::positron) {
187 if (pidmap[truth_trk.getPdgID()] == PIDBins::proton) {
194 for (
auto& track : tracks) {
199 std::find_if(truthTrackCollection_->begin(),
200 truthTrackCollection_->end(), [&](
const ldmx::Track& tt) {
201 return tt.getTrackID() == track.getTrackID();
204 double trackTruthProb = track.getTruthProb();
206 if (it != truthTrackCollection_->end() && trackTruthProb >= trackProb_cut_)
210 if (!truth_trk)
return;
212 double truth_phi = truth_trk->getPhi();
213 double truth_d0 = truth_trk->getD0();
214 double truth_z0 = truth_trk->getZ0();
215 double truth_theta = truth_trk->getTheta();
216 double truth_qop = truth_trk->getQoP();
217 double truth_p = 1. / abs(truth_trk->getQoP());
218 std::vector<double> truth_mom = truth_trk->getMomentum();
222 double truth_pt_beam =
223 std::sqrt(truth_mom[1] * truth_mom[1] + truth_mom[2] * truth_mom[2]);
225 double truth_beam_angle = std::atan2(truth_pt_beam, truth_mom[0]);
237 for (
auto trackHit : track.getMeasurementsIdxs()) {
239 measurements.at(trackHit).getLayer());
244 if (pidmap.count(truth_trk->getPdgID()) != 0) {
249 if (pidmap[truth_trk->getPdgID()] == PIDBins::kminus) {
253 if (pidmap[truth_trk->getPdgID()] == PIDBins::kplus) {
257 if (pidmap[truth_trk->getPdgID()] == PIDBins::piminus) {
261 if (pidmap[truth_trk->getPdgID()] == PIDBins::piplus) {
265 if (pidmap[truth_trk->getPdgID()] == PIDBins::electron) {
269 if (pidmap[truth_trk->getPdgID()] == PIDBins::positron) {
273 if (pidmap[truth_trk->getPdgID()] == PIDBins::proton) {
281void TrackingRecoDQM::TrackMonitoring(
282 const std::vector<ldmx::Track>& tracks,
283 const std::vector<ldmx::Measurement>& measurements,
const std::string title,
284 const bool& doDetail,
const bool& doTruth) {
285 for (
auto& track : tracks) {
287 double trk_d0 = track.getD0();
288 double trk_z0 = track.getZ0();
289 double trk_qop = track.getQoP();
290 double trk_theta = track.getTheta();
291 double trk_phi = track.getPhi();
292 double trk_p = 1. / abs(trk_qop);
293 for (
auto trackHit : track.getMeasurementsIdxs()) {
295 measurements.at(trackHit).getLayer());
298 std::vector<double> trk_mom = track.getMomentum();
302 std::sqrt(trk_mom[0] * trk_mom[0] + trk_mom[1] * trk_mom[1]);
306 std::sqrt(trk_mom[1] * trk_mom[1] + trk_mom[2] * trk_mom[2]);
309 Acts::BoundSquareMatrix cov =
310 tracking::sim::utils::unpackCov(track.getPerigeeCov());
312 double sigmad0 = sqrt(
313 cov(Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc0));
314 double sigmaz0 = sqrt(
315 cov(Acts::BoundIndices::eBoundLoc1, Acts::BoundIndices::eBoundLoc1));
317 sqrt(cov(Acts::BoundIndices::eBoundPhi, Acts::BoundIndices::eBoundPhi));
318 double sigmatheta = sqrt(
319 cov(Acts::BoundIndices::eBoundTheta, Acts::BoundIndices::eBoundTheta));
320 double sigmaqop = sqrt(cov(Acts::BoundIndices::eBoundQOverP,
321 Acts::BoundIndices::eBoundQOverP));
322 double sigmap = (1. / trk_qop) * (1. / trk_qop) * sigmaqop;
343 track.getChi2() / track.getNdf());
355 double p = std::abs(1. / trk_qop);
357 histograms_.
fill(title +
"z0_err_vs_p", std::abs(1. / trk_qop), sigmaz0);
358 histograms_.
fill(title +
"p_err_vs_p", std::abs(1. / trk_qop), sigmap);
360 if (track.getNhits() == 8)
362 else if (track.getNhits() == 9)
364 else if (track.getNhits() == 10)
372 auto it = std::find_if(truthTrackCollection_->begin(),
373 truthTrackCollection_->end(),
375 return tt.getTrackID() == track.getTrackID();
378 double trackTruthProb = track.getTruthProb();
380 if (it != truthTrackCollection_->end() &&
381 trackTruthProb >= trackProb_cut_)
386 double truth_d0 = truth_trk->getD0();
387 double truth_z0 = truth_trk->getZ0();
388 double truth_phi = truth_trk->getPhi();
389 double truth_theta = truth_trk->getTheta();
390 double truth_qop = truth_trk->getQoP();
391 double truth_p = 1. / abs(truth_trk->getQoP());
392 std::vector<double> truth_mom = truth_trk->getMomentum();
395 double truth_pt_beam = std::sqrt(truth_mom[1] * truth_mom[1] +
396 truth_mom[2] * truth_mom[2]);
405 double res_d0 = trk_d0 - truth_d0;
406 double res_z0 = trk_z0 - truth_z0;
407 double res_phi = trk_phi - truth_phi;
408 double res_theta = trk_theta - truth_theta;
409 double res_qop = trk_qop - truth_qop;
410 double res_p = trk_p - truth_p;
411 double res_pt_beam = pt_beam - truth_pt_beam;
421 double pull_d0 = res_d0 / sigmad0;
422 double pull_z0 = res_z0 / sigmaz0;
423 double pull_phi = res_phi / sigmaphi;
424 double pull_theta = res_theta / sigmatheta;
425 double pull_qop = res_qop / sigmaqop;
426 double pull_p = res_p / sigmap;
451 if (track.getNhits() == 8)
453 else if (track.getNhits() == 9)
455 else if (track.getNhits() == 10)
468 ldmx::TrackStateType ts_type,
469 const std::string& ts_title) {
470 for (
auto& track : tracks) {
475 std::find_if(truthTrackCollection_->begin(),
476 truthTrackCollection_->end(), [&](
const ldmx::Track& tt) {
477 return tt.getTrackID() == track.getTrackID();
480 double trackTruthProb = track.getTruthProb();
482 if (it != truthTrackCollection_->end() && trackTruthProb >= trackProb_cut_)
486 if (!truth_trk)
continue;
490 auto trk_ts = track.getTrackState(ts_type);
491 auto truth_ts = truth_trk->getTrackState(ts_type);
493 if (!trk_ts.has_value())
continue;
495 if (!truth_ts.has_value())
continue;
500 ldmx_log(debug) <<
"Unpacking covariance matrix" << std::endl;
501 Acts::BoundSquareMatrix cov =
502 tracking::sim::utils::unpackCov(TargetState.cov);
504 [[maybe_unused]]
double sigmaloc0 = sqrt(
505 cov(Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc0));
506 [[maybe_unused]]
double sigmaloc1 = sqrt(
507 cov(Acts::BoundIndices::eBoundLoc1, Acts::BoundIndices::eBoundLoc1));
508 [[maybe_unused]]
double sigmaphi =
509 sqrt(cov(Acts::BoundIndices::eBoundPhi, Acts::BoundIndices::eBoundPhi));
510 [[maybe_unused]]
double sigmatheta = sqrt(
511 cov(Acts::BoundIndices::eBoundTheta, Acts::BoundIndices::eBoundTheta));
512 [[maybe_unused]]
double sigmaqop = sqrt(cov(
513 Acts::BoundIndices::eBoundQOverP, Acts::BoundIndices::eBoundQOverP));
515 double trk_qop = track.getQoP();
516 double trk_p = 1. / abs(trk_qop);
518 double track_state_loc0 = TargetState.params[0];
519 double track_state_loc1 = TargetState.params[1];
520 [[maybe_unused]]
double track_state_phi = TargetState.params[2];
521 [[maybe_unused]]
double track_state_theta = TargetState.params[3];
522 [[maybe_unused]]
double track_state_p = TargetState.params[4];
524 double truth_state_loc0 = truthTargetState.params[0];
525 double truth_state_loc1 = truthTargetState.params[1];
526 [[maybe_unused]]
double truth_state_phi = truthTargetState.params[2];
527 [[maybe_unused]]
double truth_state_theta = truthTargetState.params[3];
528 [[maybe_unused]]
double truth_state_p = truthTargetState.params[4];
531 if (TargetState.params.size() < 5)
continue;
533 histograms_.
fill(title_ +
"trk_" + ts_title +
"_loc0", track_state_loc0);
534 histograms_.
fill(title_ +
"trk_" + ts_title +
"_loc1", track_state_loc1);
540 track_state_loc0 - truth_state_loc0);
542 track_state_loc1 - truth_state_loc1);
546 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
548 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
554 track.getNhits(), track_state_loc0 - truth_state_loc0);
556 track.getNhits(), track_state_loc1 - truth_state_loc1);
561 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
564 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
568 track_state_loc0 - truth_state_loc0);
570 track_state_loc1 - truth_state_loc1);
574 (track_state_loc0 - truth_state_loc0) / sigmaloc0);
576 (track_state_loc1 - truth_state_loc1) / sigmaloc1);
581void TrackingRecoDQM::sortTracks(
const std::vector<ldmx::Track>& tracks,
582 std::vector<ldmx::Track>& uniqueTracks,
583 std::vector<ldmx::Track>& duplicateTracks,
584 std::vector<ldmx::Track>& fakeTracks) {
586 std::vector<ldmx::Track> sortedTracks = tracks;
589 std::sort(sortedTracks.begin(), sortedTracks.end(),
591 return t1.getTrackID() < t2.getTrackID();
595 for (
size_t i = 0; i < sortedTracks.size(); i++) {
596 if (sortedTracks[i].getTruthProb() < trackProb_cut_)
597 fakeTracks.push_back(sortedTracks[i]);
601 if (uniqueTracks.size() == 0 ||
602 sortedTracks[i].getTrackID() != sortedTracks[i - 1].getTrackID()) {
603 uniqueTracks.push_back(sortedTracks[i]);
609 else if (sortedTracks[i].getTruthProb() >
610 uniqueTracks.back().getTruthProb()) {
611 duplicateTracks.push_back(uniqueTracks.back());
612 uniqueTracks.back() = sortedTracks[i];
616 duplicateTracks.push_back(sortedTracks[i]);
623 if (uniqueTracks.size() + duplicateTracks.size() + fakeTracks.size() !=
625 std::cerr <<
"Error: unique and duplicate tracks vectors do not add up to "
626 "original tracks vector"
633 std::cout <<
"Unique tracks:" << std::endl;
635 std::cout <<
"Track ID: " << track.getTrackID()
636 <<
", Truth Prob: " << track.getTruthProb() << std::endl;
638 std::cout <<
"Duplicate tracks:" << std::endl;
640 std::cout <<
"Track ID: " << track.getTrackID()
641 <<
", Truth Prob: " << track.getTruthProb() << std::endl;
643 std::cout <<
"Fake tracks:" << std::endl;
645 std::cout <<
"Track ID: " << track.getTrackID()
646 <<
", 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.
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.