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