36 beam_energy_mev_ = parameters.
get<
double>(
"beam_energy");
37 num_ecal_layers_ = parameters.
get<
int>(
"num_ecal_layers");
38 rem_dist_file_name_ = parameters.
get<std::string>(
"rem_dist_file");
40 parameters.
get<std::string>(
"collection_name_included");
41 collection_name_excluded_ =
42 parameters.
get<std::string>(
"collection_name_excluded");
43 rec_coll_name_ = parameters.
get<std::string>(
"rec_coll_name");
44 rec_pass_name_ = parameters.
get<std::string>(
"rec_pass_name");
45 ecal_sp_hits_pass_name_ =
46 parameters.
get<std::string>(
"ecal_sp_hits_pass_name");
47 ecal_sim_pass_name_ = parameters.
get<std::string>(
"ecal_sim_pass_name");
48 recoil_from_tracking_ = parameters.
get<
bool>(
"recoil_from_tracking");
49 track_coll_name_ = parameters.
get<std::string>(
"track_coll_name");
50 track_pass_name_ = parameters.
get<std::string>(
"track_pass_name");
51 n_electrons_ = parameters.
get<
int>(
56 if (!std::ifstream(rem_dist_file_name_).good()) {
57 EXCEPTION_RAISE(
"EcalRecoilRemovalProcessor",
58 "The specified removal distances file '" +
59 rem_dist_file_name_ +
"' does not exist!");
61 std::ifstream remdistfile(rem_dist_file_name_);
62 std::string line, value;
65 std::getline(remdistfile, line);
66 std::vector<float> values;
69 while (std::getline(remdistfile, line)) {
70 std::stringstream ss(line);
72 while (std::getline(ss, value,
',')) {
73 float f_value = (value !=
"") ? std::stof(value) : -1.0;
74 values.push_back(f_value);
76 rem_dist_values_.push_back(values);
80 if (!recoil_from_tracking_) {
81 EXCEPTION_RAISE(
"EcalRecoilRemovalProcessor",
82 "The processor is currently not configured to use sim "
83 "information! Please set recoil_from_tracking = True");
91 auto start = std::chrono::high_resolution_clock::now();
96 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
98 std::vector<std::array<float, 3>> ele_p;
99 std::vector<std::array<float, 3>> ele_pos;
100 std::vector<bool> fiducial_in_tracker;
102 auto setup_finish = std::chrono::high_resolution_clock::now();
103 profiling_map_[
"setup"] +=
104 std::chrono::duration<float, std::milli>(setup_finish - start).count();
164 if (recoil_from_tracking_) {
165 ldmx_log(trace) <<
" Get recoil tracks collection";
169 event.getCollection<
ldmx::Track>(track_coll_name_, track_pass_name_)};
171 ldmx_log(trace) <<
" Propagate the recoil ele to the ECAL";
172 auto ele_track_states =
174 if (!ele_track_states.empty()) {
175 for (
int i = 0; i < ele_track_states.size(); ++i) {
176 std::vector<float>& recoil_track_states_ecal = ele_track_states[i];
177 std::array<float, 3> recoil_pos;
178 std::array<float, 3> recoil_p;
181 if (!recoil_track_states_ecal.empty()) {
182 recoil_pos = {recoil_track_states_ecal[0],
183 recoil_track_states_ecal[1],
184 recoil_track_states_ecal[2]};
185 recoil_p = {(recoil_track_states_ecal[3]),
186 (recoil_track_states_ecal[4]),
187 (recoil_track_states_ecal[5])};
188 fiducial_in_tracker.push_back(
true);
190 recoil_pos = {-9999.f, -9999.f, -9999.f};
191 recoil_p = {0.f, 0.f, 0.f};
192 fiducial_in_tracker.push_back(
false);
193 ldmx_log(info) <<
" Electron trajectory is empty!";
195 ldmx_log(debug) <<
" Electron " << i + 1 <<
": set recoil_p = ("
196 << recoil_p[0] <<
", " << recoil_p[1] <<
", "
197 << recoil_p[2] <<
") and recoil_pos = ("
198 << recoil_pos[0] <<
", " << recoil_pos[1] <<
", "
199 << recoil_pos[2] <<
")";
200 ele_p.push_back(recoil_p);
201 ele_pos.push_back(recoil_pos);
204 ldmx_log(info) <<
" No valid electron tracks found in recoil tracking "
209 auto recoil_electron_finish = std::chrono::high_resolution_clock::now();
210 profiling_map_[
"recoil_electron"] +=
211 std::chrono::duration<float, std::milli>(recoil_electron_finish -
219 ldmx_log(trace) <<
" Get projected trajectories for electron and photon";
221 std::vector<std::vector<XYCoords>> ele_trajectories;
222 std::vector<float> ele_p_mag;
223 std::vector<float> ele_theta;
225 if (!ele_p.empty() && !ele_pos.empty()) {
226 for (
int i = 0; i < ele_p.size(); ++i) {
227 std::array<float, 3>& recoil_p = ele_p[i];
228 std::array<float, 3>& recoil_pos = ele_pos[i];
229 std::vector<XYCoords> ele_trajectory;
234 if ((recoil_p[2] > 0.) && (recoil_pos[0] != -9999.)) {
235 ele_trajectory = getTrajectory(recoil_p, recoil_pos);
237 ldmx_log(trace) <<
"Ele trajectory cannot be determined, pZ = "
238 << recoil_p[2] <<
" X = " << recoil_pos[0];
244 ? sqrt((recoil_p[0] * recoil_p[0]) + (recoil_p[1] * recoil_p[1]) +
245 (recoil_p[2] * recoil_p[2]))
247 float recoil_theta = recoil_p_mag > 0
248 ? acos(recoil_p[2] / recoil_p_mag) * 180.0 / M_PI
252 ele_trajectories.push_back(ele_trajectory);
253 ele_p_mag.push_back(recoil_p_mag);
254 ele_theta.push_back(recoil_theta);
259 auto trajectories_finish = std::chrono::high_resolution_clock::now();
260 profiling_map_[
"trajectories"] +=
261 std::chrono::duration<float, std::milli>(trajectories_finish -
262 recoil_electron_finish)
269 ldmx_log(trace) <<
" Build recoil removal distances vector";
270 std::vector<float> rem_dist_values_bin_0(rem_dist_values_[0].begin() + 4,
271 rem_dist_values_[0].end());
272 std::vector<std::vector<float>> removal_distances;
274 if (!ele_trajectories.empty()) {
275 for (
int k = 0; k < ele_p_mag.size(); ++k) {
276 float theta_min, theta_max, p_min, p_max;
278 std::vector<float> rec_rem_dists = rem_dist_values_bin_0;
279 float& recoil_p_mag = ele_p_mag[k];
280 float& recoil_theta = ele_theta[k];
283 for (
int i = 0; i < rem_dist_values_.size(); i++) {
284 theta_min = rem_dist_values_[i][0];
285 theta_max = rem_dist_values_[i][1];
286 p_min = rem_dist_values_[i][2];
287 p_max = rem_dist_values_[i][3];
290 if (theta_min != -1.0) {
291 inrange = inrange && (recoil_theta >= theta_min);
293 if (theta_max != -1.0) {
294 inrange = inrange && (recoil_theta < theta_max);
297 inrange = inrange && (recoil_p_mag >= p_min);
300 inrange = inrange && (recoil_p_mag < p_max);
303 std::vector<float> rem_dist_values_bini(
304 rem_dist_values_[i].begin() + 4, rem_dist_values_[i].end());
305 rec_rem_dists = rem_dist_values_bini;
308 removal_distances.push_back(rec_rem_dists);
312 auto rem_dist_finish = std::chrono::high_resolution_clock::now();
313 profiling_map_[
"rem_dist"] += std::chrono::duration<float, std::milli>(
314 rem_dist_finish - trajectories_finish)
322 const std::vector<ldmx::EcalHit> ecal_rec_hits =
323 event.getCollection<
ldmx::EcalHit>(rec_coll_name_, rec_pass_name_);
325 std::vector<ldmx::EcalHit> ecal_rec_hits_inc;
326 std::vector<ldmx::EcalHit> ecal_rec_hits_exc;
330 if (!ele_trajectories.empty()) {
331 ldmx_log(trace) <<
" ======== EcalRecHitInc List (length"
332 << ecal_rec_hits_inc.size() <<
") ========";
338 XYCoords xy_pair = std::make_pair(x, y);
341 for (
int i = 0; i < ele_trajectories.size(); ++i) {
342 std::vector<XYCoords>& ele_trajectory = ele_trajectories[i];
343 std::vector<float>& rec_rem_dists = removal_distances[i];
345 float dist_ele_traj =
347 ele_trajectory.size()
348 ? sqrt(pow((xy_pair.first - ele_trajectory[
id.layer()].first),
350 pow((xy_pair.second - ele_trajectory[
id.layer()].second),
353 if (dist_ele_traj == -1.0) {
354 ldmx_log(trace) <<
" ele_trajectory does not exist; KEEP";
356 }
else if (dist_ele_traj <=
357 (rec_rem_dists[
id.layer()])) {
360 ldmx_log(trace) <<
" dist_ele_traj = " << dist_ele_traj
361 <<
" <= " << rec_rem_dists[
id.layer()] <<
"; DISCARD";
364 ldmx_log(trace) <<
" dist_ele_traj = " << dist_ele_traj
365 <<
" > " << rec_rem_dists[
id.layer()] <<
"; KEEP";
372 ecal_rec_hits_inc.emplace_back(hit);
374 ecal_rec_hits_exc.emplace_back(hit);
378 ldmx_log(trace) <<
" ======== END OF ecal_rec_hit List ========";
380 ecal_rec_hits_inc = ecal_rec_hits;
382 ldmx_log(info) <<
" Removed " << ecal_rec_hits_exc.size()
383 <<
" hits within recoil electron RoC; "
384 << ecal_rec_hits_inc.size() <<
" hits remaining of "
385 << ecal_rec_hits.size();
390 event.add(collection_name_excluded_, ecal_rec_hits_exc);
392 auto recoil_removal_finish = std::chrono::high_resolution_clock::now();
393 profiling_map_[
"recoil_removal"] +=
394 std::chrono::duration<float, std::milli>(recoil_removal_finish -
398 auto end = std::chrono::high_resolution_clock::now();
399 auto time_diff = end - start;
401 std::chrono::duration<float, std::milli>(time_diff).count();