LDMX Software
EcalTrackAnalyzer.cxx
Go to the documentation of this file.
1
7
8#include <cmath>
9
10#include "Tracking/Event/Track.h"
11
12namespace dqm {
13
15 track_collection_ = ps.get<std::string>("track_collection");
16 track_pass_name_ = ps.get<std::string>("track_pass_name");
17 rec_hit_collection_ = ps.get<std::string>("rec_hit_collection");
18 rec_hit_pass_name_ = ps.get<std::string>("rec_hit_pass_name");
19}
20
22 // Check if track collection exists
24 ldmx_log(debug) << "ECAL track collection does not exist";
25 return;
26 }
27
28 // Get ECAL tracks
29 const auto& ecal_tracks =
30 event.getCollection<ldmx::Track>(track_collection_, track_pass_name_);
31
32 int n_tracks = ecal_tracks.size();
33 histograms_.fill("n_tracks", n_tracks);
34
35 if (n_tracks == 0) {
36 return;
37 }
38
39 // Loop over tracks
40 for (size_t i_track = 0; i_track < ecal_tracks.size(); ++i_track) {
41 const auto& track = ecal_tracks[i_track];
42
43 // Track quality
44 double chi2 = track.getChi2();
45 int ndf = track.getNdf();
46 int nhits = track.getNhits();
47
48 histograms_.fill("track_chi2", chi2);
49 histograms_.fill("track_ndf", ndf);
50 histograms_.fill("track_nhits", nhits);
51
52 if (ndf > 0) {
53 histograms_.fill("track_chi2_ndf", chi2 / ndf);
54 }
55
56 // Track parameters
57 double d0 = track.getD0();
58 double z0 = track.getZ0();
59 double phi = track.getPhi();
60 double theta = track.getTheta();
61 double qop = track.getQoP();
62 int charge = track.getCharge();
63
64 histograms_.fill("track_d0", d0);
65 histograms_.fill("track_z0", z0);
66 histograms_.fill("track_phi", phi);
67 histograms_.fill("track_theta", theta);
68 histograms_.fill("track_qop", qop);
69 histograms_.fill("track_charge", charge);
70
71 // Momentum
72 double p = 0;
73 if (std::abs(qop) > 1e-9) {
74 p = 1.0 / std::abs(qop);
75 }
76 histograms_.fill("track_p", p);
77
78 // Momentum components (approximate from angles and magnitude)
79 double px = p * std::sin(theta) * std::cos(phi);
80 double py = p * std::sin(theta) * std::sin(phi);
81 double pz = p * std::cos(theta);
82
83 double pt = std::sqrt(px * px + py * py);
84 histograms_.fill("track_px", px);
85 histograms_.fill("track_py", py);
86 histograms_.fill("track_pz", pz);
87 histograms_.fill("track_pt", pt);
88
89 // Position at ECAL front (from d0, z0)
90 // d0 and z0 are in the perigee frame
91 double x = -d0 * std::sin(phi); // Approximate x position
92 double y = d0 * std::cos(phi); // Approximate y position
93
94 histograms_.fill("track_x", x);
95 histograms_.fill("track_y", y);
96 histograms_.fill("track_xy", x, y);
97
98 // 2D correlations
99 histograms_.fill("track_nhits_vs_chi2", nhits, chi2);
100 histograms_.fill("track_nhits_vs_chi2_ndf", nhits,
101 (ndf > 0) ? chi2 / ndf : 0.0);
102 histograms_.fill("track_chi2_vs_nhits", chi2, nhits);
103 histograms_.fill("track_p_vs_chi2", p, chi2);
104 histograms_.fill("track_p_vs_nhits", p, nhits);
105 histograms_.fill("track_p_vs_theta", p, theta);
106
107 // If multiple tracks, fill special histograms
108 if (n_tracks > 1) {
109 histograms_.fill("track_p_multitracks", p);
110
111 // Calculate angular separation between tracks
112 for (size_t j_track = i_track + 1; j_track < ecal_tracks.size();
113 ++j_track) {
114 const auto& other_track = ecal_tracks[j_track];
115
116 double phi1 = track.getPhi();
117 double theta1 = track.getTheta();
118 double phi2 = other_track.getPhi();
119 double theta2 = other_track.getTheta();
120
121 // Direction vectors
122 double dx1 = std::sin(theta1) * std::cos(phi1);
123 double dy1 = std::sin(theta1) * std::sin(phi1);
124 double dz1 = std::cos(theta1);
125
126 double dx2 = std::sin(theta2) * std::cos(phi2);
127 double dy2 = std::sin(theta2) * std::sin(phi2);
128 double dz2 = std::cos(theta2);
129
130 // Dot product
131 double dot = dx1 * dx2 + dy1 * dy2 + dz1 * dz2;
132 double angle = std::acos(std::max(-1.0, std::min(1.0, dot)));
133
134 histograms_.fill("track_separation", angle);
135 }
136 }
137 }
138
139 ldmx_log(debug) << "Analyzed " << n_tracks << " ECAL tracks";
140}
141
142} // namespace dqm
143
Analysis of ECAL tracks produced by ACTS track finder.
#define DECLARE_ANALYZER(CLASS)
Macro which allows the framework to construct an analyzer given its name during configuration.
DQM analyzer for ECAL tracks fitted with ACTS zero-B field CKF.
std::string rec_hit_pass_name_
Pass name for RecHits.
void analyze(const framework::Event &event) override
Analyze the event.
void configure(framework::config::Parameters &ps) override
Configure the analyzer.
std::string track_collection_
ECAL track collection name.
std::string rec_hit_collection_
ECAL RecHit collection (for layer occupancy)
std::string track_pass_name_
Pass name for tracks.
HistogramPool histograms_
helper object for making and filling histograms
Implements an event buffer system for storing event data.
Definition Event.h:40
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:107
void fill(const std::string &name, const T &val)
Fill a 1D histogram.
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:26
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75
Implementation of a track object.
Definition Track.h:54