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