28 beam_energy_mev_ = parameters.
get<
double>(
"beam_energy");
29 num_ecal_layers_ = parameters.
get<
int>(
"num_ecal_layers");
30 rem_dist_file_name_ = parameters.
get<std::string>(
"rem_dist_file");
32 parameters.
get<std::string>(
"collection_name_included");
33 collection_name_excluded_ =
34 parameters.
get<std::string>(
"collection_name_excluded");
35 rec_coll_name_ = parameters.
get<std::string>(
"rec_coll_name");
36 rec_pass_name_ = parameters.
get<std::string>(
"rec_pass_name");
37 ecal_sp_hits_pass_name_ =
38 parameters.
get<std::string>(
"ecal_sp_hits_pass_name");
39 ecal_sim_pass_name_ = parameters.
get<std::string>(
"ecal_sim_pass_name");
40 recoil_from_tracking_ = parameters.
get<
bool>(
"recoil_from_tracking");
41 track_coll_name_ = parameters.
get<std::string>(
"track_coll_name");
42 track_pass_name_ = parameters.
get<std::string>(
"track_pass_name");
43 n_electrons_ = parameters.
get<
int>(
48 if (!std::ifstream(rem_dist_file_name_).good()) {
49 EXCEPTION_RAISE(
"EcalRecoilRemovalProcessor",
50 "The specified removal distances file '" +
51 rem_dist_file_name_ +
"' does not exist!");
53 std::ifstream remdistfile(rem_dist_file_name_);
54 std::string line, value;
57 std::getline(remdistfile, line);
58 std::vector<float> values;
61 while (std::getline(remdistfile, line)) {
62 std::stringstream ss(line);
64 while (std::getline(ss, value,
',')) {
65 float f_value = (value !=
"") ? std::stof(value) : -1.0;
66 values.push_back(f_value);
68 rem_dist_values_.push_back(values);
72 if (!recoil_from_tracking_) {
73 EXCEPTION_RAISE(
"EcalRecoilRemovalProcessor",
74 "The processor is currently not configured to use sim "
75 "information! Please set recoil_from_tracking = True");
83 auto start = std::chrono::high_resolution_clock::now();
88 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
90 std::vector<std::array<float, 3>> ele_p;
91 std::vector<std::array<float, 3>> ele_pos;
92 std::vector<bool> fiducial_in_tracker;
94 auto setup_finish = std::chrono::high_resolution_clock::now();
95 profiling_map_[
"setup"] +=
96 std::chrono::duration<float, std::milli>(setup_finish - start).count();
156 if (recoil_from_tracking_) {
157 ldmx_log(trace) <<
" Get recoil tracks collection";
161 event.getCollection<
ldmx::Track>(track_coll_name_, track_pass_name_)};
163 ldmx_log(trace) <<
" Propagate the recoil ele to the ECAL";
164 auto ele_track_states =
166 if (!ele_track_states.empty()) {
167 for (
int i = 0; i < ele_track_states.size(); ++i) {
168 std::vector<float>& recoil_track_states_ecal = ele_track_states[i];
169 std::array<float, 3> recoil_pos;
170 std::array<float, 3> recoil_p;
173 if (!recoil_track_states_ecal.empty()) {
174 recoil_pos = {recoil_track_states_ecal[0],
175 recoil_track_states_ecal[1],
176 recoil_track_states_ecal[2]};
177 recoil_p = {(recoil_track_states_ecal[3]),
178 (recoil_track_states_ecal[4]),
179 (recoil_track_states_ecal[5])};
180 fiducial_in_tracker.push_back(
true);
182 recoil_pos = {-9999.f, -9999.f, -9999.f};
183 recoil_p = {0.f, 0.f, 0.f};
184 fiducial_in_tracker.push_back(
false);
185 ldmx_log(info) <<
" Electron trajectory is empty!";
187 ldmx_log(debug) <<
" Electron " << i + 1 <<
": set recoil_p = ("
188 << recoil_p[0] <<
", " << recoil_p[1] <<
", "
189 << recoil_p[2] <<
") and recoil_pos = ("
190 << recoil_pos[0] <<
", " << recoil_pos[1] <<
", "
191 << recoil_pos[2] <<
")";
192 ele_p.push_back(recoil_p);
193 ele_pos.push_back(recoil_pos);
196 ldmx_log(info) <<
" No valid electron tracks found in recoil tracking "
201 auto recoil_electron_finish = std::chrono::high_resolution_clock::now();
202 profiling_map_[
"recoil_electron"] +=
203 std::chrono::duration<float, std::milli>(recoil_electron_finish -
211 ldmx_log(trace) <<
" Get projected trajectories for electron and photon";
213 std::vector<std::vector<XYCoords>> ele_trajectories;
214 std::vector<float> ele_p_mag;
215 std::vector<float> ele_theta;
217 if (!ele_p.empty() && !ele_pos.empty()) {
218 for (
int i = 0; i < ele_p.size(); ++i) {
219 std::array<float, 3>& recoil_p = ele_p[i];
220 std::array<float, 3>& recoil_pos = ele_pos[i];
221 std::vector<XYCoords> ele_trajectory;
226 if ((recoil_p[2] > 0.) && (recoil_pos[0] != -9999.)) {
227 ele_trajectory = getTrajectory(recoil_p, recoil_pos);
229 ldmx_log(trace) <<
"Ele trajectory cannot be determined, pZ = "
230 << recoil_p[2] <<
" X = " << recoil_pos[0];
236 ? sqrt((recoil_p[0] * recoil_p[0]) + (recoil_p[1] * recoil_p[1]) +
237 (recoil_p[2] * recoil_p[2]))
239 float recoil_theta = recoil_p_mag > 0
240 ? acos(recoil_p[2] / recoil_p_mag) * 180.0 / M_PI
244 ele_trajectories.push_back(ele_trajectory);
245 ele_p_mag.push_back(recoil_p_mag);
246 ele_theta.push_back(recoil_theta);
251 auto trajectories_finish = std::chrono::high_resolution_clock::now();
252 profiling_map_[
"trajectories"] +=
253 std::chrono::duration<float, std::milli>(trajectories_finish -
254 recoil_electron_finish)
261 ldmx_log(trace) <<
" Build recoil removal distances vector";
262 std::vector<float> rem_dist_values_bin_0(rem_dist_values_[0].begin() + 4,
263 rem_dist_values_[0].end());
264 std::vector<std::vector<float>> removal_distances;
266 if (!ele_trajectories.empty()) {
267 for (
int k = 0; k < ele_p_mag.size(); ++k) {
268 float theta_min, theta_max, p_min, p_max;
270 std::vector<float> rec_rem_dists = rem_dist_values_bin_0;
271 float& recoil_p_mag = ele_p_mag[k];
272 float& recoil_theta = ele_theta[k];
275 for (
int i = 0; i < rem_dist_values_.size(); i++) {
276 theta_min = rem_dist_values_[i][0];
277 theta_max = rem_dist_values_[i][1];
278 p_min = rem_dist_values_[i][2];
279 p_max = rem_dist_values_[i][3];
282 if (theta_min != -1.0) {
283 inrange = inrange && (recoil_theta >= theta_min);
285 if (theta_max != -1.0) {
286 inrange = inrange && (recoil_theta < theta_max);
289 inrange = inrange && (recoil_p_mag >= p_min);
292 inrange = inrange && (recoil_p_mag < p_max);
295 std::vector<float> rem_dist_values_bini(
296 rem_dist_values_[i].begin() + 4, rem_dist_values_[i].end());
297 rec_rem_dists = rem_dist_values_bini;
300 removal_distances.push_back(rec_rem_dists);
304 auto rem_dist_finish = std::chrono::high_resolution_clock::now();
305 profiling_map_[
"rem_dist"] += std::chrono::duration<float, std::milli>(
306 rem_dist_finish - trajectories_finish)
314 const std::vector<ldmx::EcalHit> ecal_rec_hits =
315 event.getCollection<
ldmx::EcalHit>(rec_coll_name_, rec_pass_name_);
317 std::vector<ldmx::EcalHit> ecal_rec_hits_inc;
318 std::vector<ldmx::EcalHit> ecal_rec_hits_exc;
322 if (!ele_trajectories.empty()) {
323 ldmx_log(trace) <<
" ======== EcalRecHitInc List (length"
324 << ecal_rec_hits_inc.size() <<
") ========";
330 XYCoords xy_pair = std::make_pair(x, y);
333 for (
int i = 0; i < ele_trajectories.size(); ++i) {
334 std::vector<XYCoords>& ele_trajectory = ele_trajectories[i];
335 std::vector<float>& rec_rem_dists = removal_distances[i];
337 float dist_ele_traj =
339 ele_trajectory.size()
340 ? sqrt(pow((xy_pair.first - ele_trajectory[
id.layer()].first),
342 pow((xy_pair.second - ele_trajectory[
id.layer()].second),
345 if (dist_ele_traj == -1.0) {
346 ldmx_log(trace) <<
" ele_trajectory does not exist; KEEP";
348 }
else if (dist_ele_traj <=
349 (rec_rem_dists[
id.layer()])) {
352 ldmx_log(trace) <<
" dist_ele_traj = " << dist_ele_traj
353 <<
" <= " << rec_rem_dists[
id.layer()] <<
"; DISCARD";
356 ldmx_log(trace) <<
" dist_ele_traj = " << dist_ele_traj
357 <<
" > " << rec_rem_dists[
id.layer()] <<
"; KEEP";
364 ecal_rec_hits_inc.emplace_back(hit);
366 ecal_rec_hits_exc.emplace_back(hit);
370 ldmx_log(trace) <<
" ======== END OF ecal_rec_hit List ========";
372 ecal_rec_hits_inc = ecal_rec_hits;
374 ldmx_log(info) <<
" Removed " << ecal_rec_hits_exc.size()
375 <<
" hits within recoil electron RoC; "
376 << ecal_rec_hits_inc.size() <<
" hits remaining of "
377 << ecal_rec_hits.size();
382 event.add(collection_name_excluded_, ecal_rec_hits_exc);
384 auto recoil_removal_finish = std::chrono::high_resolution_clock::now();
385 profiling_map_[
"recoil_removal"] +=
386 std::chrono::duration<float, std::milli>(recoil_removal_finish -
390 auto end = std::chrono::high_resolution_clock::now();
391 auto time_diff = end - start;
393 std::chrono::duration<float, std::milli>(time_diff).count();