LDMX Software
EcalHelper.cxx
1#include "Ecal/EcalHelper.h"
2
3#include <algorithm>
4#include <cmath>
5
6namespace ecal {
7
8std::vector<float> trackProp(const ldmx::Tracks& tracks,
9 ldmx::TrackStateType ts_type,
10 const std::string& ts_title) {
11 // Vector to hold the new track state variables
12 std::vector<float> new_track_states;
13
14 // Return if no tracks
15 if (tracks.empty()) return new_track_states;
16
17 // Otherwise loop on the tracks
18 for (auto& track : tracks) {
19 // Get track state for ts_type
20 auto trk_ts = track.getTrackState(ts_type);
21 // Continue if there's no value
22 if (!trk_ts.has_value()) continue;
23 ldmx::Track::TrackState ecal_track_state = trk_ts.value();
24
25 // Check that the track state is filled
26 if (ecal_track_state.pos_.size() < 3 || ecal_track_state.mom_.size() < 3)
27 continue;
28
29 // pos_ is (x, y, z) in mm (LDMX global); mom_ is (px, py, pz) in MeV
30 new_track_states.push_back(static_cast<float>(ecal_track_state.pos_[0]));
31 new_track_states.push_back(static_cast<float>(ecal_track_state.pos_[1]));
32 new_track_states.push_back(static_cast<float>(ecal_track_state.pos_[2]));
33 new_track_states.push_back(static_cast<float>(ecal_track_state.mom_[0]));
34 new_track_states.push_back(static_cast<float>(ecal_track_state.mom_[1]));
35 new_track_states.push_back(static_cast<float>(ecal_track_state.mom_[2]));
36
37 // Break after getting the first valid track state
38 // TODO: interface this with CLUE to make sure the propagated track
39 // has an associated cluster in the ECAL
40 break;
41 }
42
43 return new_track_states;
44}
45
46// Returns 'ele_count' tracks with the greatest transverse momentum that is also
47// valid at the Ecal face
48std::vector<std::vector<float>> pTTrackProp(const ldmx::Tracks& tracks,
49 int ele_count) {
50 // Vector to hold the new track state variables, indexed by pT
51 std::vector<std::pair<float, std::vector<float>>> new_track_states;
52
53 // Return empty vector if no tracks
54 if (tracks.empty()) return {};
55
56 // Otherwise loop on the tracks
57 for (auto& track : tracks) {
58 // Vector to hold track state parameters for a single track
59 std::vector<float> track_state_vars;
60 track_state_vars.reserve(6);
61 // Get track state for Ecal
62 auto trk_ts = track.getTrackState(ldmx::TrackStateType::AtECAL);
63 // Continue if there's no value
64 if (!trk_ts.has_value()) continue;
65 ldmx::Track::TrackState ecal_track_state = trk_ts.value();
66
67 // Check that the track state is filled
68 if (ecal_track_state.pos_.size() < 3 || ecal_track_state.mom_.size() < 3)
69 continue;
70
71 // Calculate transverse momentum
72 float transverse_momentum =
73 sqrt((ecal_track_state.mom_[0] * ecal_track_state.mom_[0]) +
74 (ecal_track_state.mom_[1] * ecal_track_state.mom_[1]));
75
76 // store state variables
77 track_state_vars.push_back(ecal_track_state.pos_[0]);
78 track_state_vars.push_back(ecal_track_state.pos_[1]);
79 track_state_vars.push_back(ecal_track_state.pos_[2]);
80 track_state_vars.push_back(ecal_track_state.mom_[0]);
81 track_state_vars.push_back(ecal_track_state.mom_[1]);
82 track_state_vars.push_back(ecal_track_state.mom_[2]);
83
84 // index track by total momentum into output
85 new_track_states.emplace_back(transverse_momentum,
86 std::move(track_state_vars));
87 }
88
89 // filters to get only the [ele_count] number of highest pT tracks
90 std::sort(new_track_states.begin(), new_track_states.end(),
91 [](const auto& a, const auto& b) {
92 return a.first > b.first;
93 }); // sort descending
94 if (new_track_states.size() > ele_count) new_track_states.resize(ele_count);
95
96 // Outputs the 'ele_count' track states themselves without the momentum
97 // indexing
98 std::vector<std::vector<float>> max_p_t_track_states;
99 max_p_t_track_states.reserve(new_track_states.size());
100 std::transform(std::make_move_iterator(new_track_states.begin()),
101 std::make_move_iterator(new_track_states.end()),
102 std::back_inserter(max_p_t_track_states),
103 [](auto&& ts) { return std::move(ts.second); });
104
105 return max_p_t_track_states;
106}
107
108// Returns a specified number `ele_count` of highest momentum tracks which are
109// valid at the Ecal face
110std::vector<std::vector<float>> momTrackProp(const ldmx::Tracks& tracks,
111 int ele_count) {
112 // Vector variable to hold track state parameters, indexed by total momentum
113 std::vector<std::pair<float, std::vector<float>>> new_track_states;
114
115 // Return empty vector if no tracks
116 if (tracks.empty()) return {};
117
118 // Otherwise loop on the tracks
119 for (auto& track : tracks) {
120 // Vector to hold track state parameters for a single track
121 std::vector<float> track_state_vars;
122 track_state_vars.reserve(6);
123 // Get track state for Ecal
124 auto trk_ts = track.getTrackState(ldmx::TrackStateType::AtECAL);
125 // Continue if there's no value
126 if (!trk_ts.has_value()) continue;
127 ldmx::Track::TrackState ecal_track_state = trk_ts.value();
128
129 // Check that the track state is filled
130 if (ecal_track_state.pos_.size() < 3 || ecal_track_state.mom_.size() < 3)
131 continue;
132
133 float total_momentum =
134 std::sqrt(ecal_track_state.mom_[0] * ecal_track_state.mom_[0] +
135 ecal_track_state.mom_[1] * ecal_track_state.mom_[1] +
136 ecal_track_state.mom_[2] * ecal_track_state.mom_[2]);
137
138 // store state variables
139 track_state_vars.push_back(ecal_track_state.pos_[0]);
140 track_state_vars.push_back(ecal_track_state.pos_[1]);
141 track_state_vars.push_back(ecal_track_state.pos_[2]);
142 track_state_vars.push_back(ecal_track_state.mom_[0]);
143 track_state_vars.push_back(ecal_track_state.mom_[1]);
144 track_state_vars.push_back(ecal_track_state.mom_[2]);
145
146 // index track by total momentum into output
147 new_track_states.emplace_back(total_momentum, std::move(track_state_vars));
148 }
149
150 // filters to get only the [ele_count] number of highest momentum tracks
151 std::sort(new_track_states.begin(), new_track_states.end(),
152 [](const auto& a, const auto& b) {
153 return a.first > b.first;
154 }); // sort descending
155 if (new_track_states.size() > ele_count) new_track_states.resize(ele_count);
156
157 // Outputs the [ele_count] track states themselves without the momentum
158 // indexing
159 std::vector<std::vector<float>> max_p_track_states;
160 max_p_track_states.reserve(new_track_states.size());
161 std::transform(std::make_move_iterator(new_track_states.begin()),
162 std::make_move_iterator(new_track_states.end()),
163 std::back_inserter(max_p_track_states),
164 [](auto&& ts) { return std::move(ts.second); });
165
166 return max_p_track_states;
167}
168
169// MIP tracking functions:
170
171float distTwoLines(ROOT::Math::XYZVector v1, ROOT::Math::XYZVector v2,
172 ROOT::Math::XYZVector w1, ROOT::Math::XYZVector w2) {
173 ROOT::Math::XYZVector e1 = v1 - v2;
174 ROOT::Math::XYZVector e2 = w1 - w2;
175 ROOT::Math::XYZVector crs = e1.Cross(e2);
176 if (crs.R() == 0) {
177 return 100.0; // arbitrary large number; edge case that shouldn't cause
178 // problems.
179 } else {
180 return std::abs(crs.Dot(v1 - w1) / crs.R());
181 }
182}
183
184float distPtToLine(ROOT::Math::XYZVector h1, ROOT::Math::XYZVector p1,
185 ROOT::Math::XYZVector p2) {
186 return ((h1 - p1).Cross(h1 - p2)).R() / (p1 - p2).R();
187}
188
189} // namespace ecal
Class that propagates tracks to the ECAL face.
std::vector< float > trackProp(const ldmx::Tracks &tracks, ldmx::TrackStateType ts_type, const std::string &ts_title)
Return a vector of parameters for a propagated recoil track.
Definition EcalHelper.cxx:8
std::vector< std::vector< float > > pTTrackProp(const ldmx::Tracks &tracks, int ele_count)
Return a vector of ele_count valid track states with the greatest transverse momentum.
float distPtToLine(ROOT::Math::XYZVector h1, ROOT::Math::XYZVector p1, ROOT::Math::XYZVector p2)
Return the minimum distance between the point h1 and the line passing through points p1 and p2.
float distTwoLines(ROOT::Math::XYZVector v1, ROOT::Math::XYZVector v2, ROOT::Math::XYZVector w1, ROOT::Math::XYZVector w2)
Returns the distance between the lines v and w, with v defined to pass through the points (v1,...
std::vector< std::vector< float > > momTrackProp(const ldmx::Tracks &tracks, int ele_count)
Return a vector of ele_count valid track states with the greatest total momentum.