LDMX Software
HcalVetoProcessor.cxx
Go to the documentation of this file.
1
9
10#include <cmath>
11
12#include "DetDescr/HcalID.h"
14
15namespace hcal {
16
18 framework::Process& process)
19 : Producer(name, process) {}
20
22 total_pe_threshold_ = parameters.get<double>("pe_threshold");
23 max_time_ = parameters.get<double>("max_time");
24 output_coll_name_ = parameters.get<std::string>("output_coll_name");
25 input_hit_coll_name_ = parameters.get<std::string>("input_hit_coll_name");
26 input_hit_pass_name_ = parameters.get<std::string>("input_hit_pass_name");
27 track_pass_name_ = parameters.get<std::string>("track_pass_name");
28
29 // A fake-hit that gets added for the rare case where no hit actually reaches
30 // the maxPE < pe check to avoid producing uninitialized memory
31 //
32 // Default constructed hits have nonsense-but predictable values and are
33 // harder to mistake for real hits
34 default_max_hit_.clear();
35 default_max_hit_.setPE(-9999);
36 default_max_hit_.setMinPE(-9999);
37 default_max_hit_.setSection(-9999);
38 default_max_hit_.setLayer(-9999);
39 default_max_hit_.setStrip(-9999);
40 default_max_hit_.setEnd(-999);
41 default_max_hit_.setTimeDiff(-9999);
42 default_max_hit_.setToaPos(-9999);
43 default_max_hit_.setToaNeg(-9999);
44 default_max_hit_.setAmplitudePos(-9999);
45 default_max_hit_.setAmplitudeNeg(-9999);
46
47 double max_depth = parameters.get<double>("max_depth", 0.);
48 if (max_depth != 0.) {
49 EXCEPTION_RAISE(
50 "InvalidParam",
51 "Earlier versions of the Hcal veto defined a max depth for "
52 "positions which is no longer implemented. Remove the "
53 "parameter (max_depth) from your configuration. See "
54 "https://github.com/LDMX-Software/Hcal/issues/61 for details");
55 }
56 back_min_pe_ = parameters.get<double>("back_min_pe");
57 exclude_recoil_ele_ = parameters.get<bool>("exclude_recoil_ele", false);
58 track_collection_ =
59 parameters.get<std::string>("track_collection", "RecoilTracks");
60 dr_from_recoil_max_ = parameters.get<double>("dr_from_recoil_max", 100);
61 inverse_skim_ = parameters.get<bool>("inverse_skim");
62}
63
65 // Get the collection of sim particles from the event
66 const std::vector<ldmx::HcalHit> hcal_rec_hits =
67 event.getCollection<ldmx::HcalHit>(input_hit_coll_name_,
68 input_hit_pass_name_);
69
70 // Where deos the recoil electron end up in the HCAL?
71 float recoil_pos_x{0.0};
72 float recoil_pos_y{0.0};
73 float recoil_pos_z{-9999.0};
74 float recoil_mom_x{-9999.0};
75 float recoil_mom_y{-9999.0};
76 float recoil_mom_z{-9999.0};
77
78 if (exclude_recoil_ele_) {
79 std::vector<float> recoil_track_states;
80 // Get the recoil track collection
81 auto recoil_tracks{
82 event.getCollection<ldmx::Track>(track_collection_, track_pass_name_)};
83
84 // Use ACTS to propagate the recoil track to the end of the magnetic field
85 // This happens to be at the ECAL face
86 ldmx::TrackStateType ts_type = ldmx::AtECAL;
87 recoil_track_states = trackProp(recoil_tracks, ts_type, "ecal");
88 if (!recoil_track_states.empty()) {
89 recoil_pos_x = recoil_track_states[0];
90 recoil_pos_y = recoil_track_states[1];
91 recoil_pos_z = recoil_track_states[2];
92 recoil_mom_x = recoil_track_states[3];
93 recoil_mom_y = recoil_track_states[4];
94 recoil_mom_z = recoil_track_states[5];
95 }
96 }
97
98 // Loop over all of the Hcal hits and calculate to total photoelectrons
99 // in the event.
100 float total_pe{0.0};
101 float max_pe{-1000};
102 int num_total_hits{0};
103 int num_valid_hits{0};
104 int num_non_recoil_hits{0};
105
106 const ldmx::HcalHit* max_pe_hit{&default_max_hit_};
107 for (const ldmx::HcalHit& hcal_hit : hcal_rec_hits) {
108 num_total_hits++;
109 // If the hit time is outside the readout window, don't consider it.
110 if (hcal_hit.getTime() >= max_time_) {
111 continue;
112 }
113
114 // Get the total PE in the bar
115 float pe = hcal_hit.getPE();
116 // Keep track of the total PE
117 total_pe += pe;
118
119 // Check that both sides of the bar have a PE value above threshold.
120 // If not, don't consider the hit. Double sided readout is only
121 // being used for the back HCal bars. For the side HCal, just
122 // use the maximum PE as before.
123 ldmx::HcalID id(hcal_hit.getID());
124 if ((id.section() == ldmx::HcalID::BACK) &&
125 (hcal_hit.getMinPE() < back_min_pe_))
126 continue;
127
128 num_valid_hits++;
129
130 // Max PE should not be caused by the recoil ele
131 if (exclude_recoil_ele_) {
132 // Get the position of this hit
133 auto hit_pos_x = hcal_hit.getXPos();
134 auto hit_pos_y = hcal_hit.getYPos();
135 auto hit_pos_z = hcal_hit.getZPos();
136 auto d_z = recoil_pos_z - hit_pos_z;
137
138 auto drift_recoil_x =
139 (d_z * (recoil_mom_x / recoil_mom_z)) + recoil_pos_x;
140 auto drift_recoil_y =
141 (d_z * (recoil_mom_y / recoil_mom_z)) + recoil_pos_y;
142 auto dx = drift_recoil_x - hit_pos_x;
143 auto dy = drift_recoil_y - hit_pos_y;
144 auto d_r_squared = dx * dx + dy * dy + d_z * d_z;
145 auto d_r = sqrt(d_r_squared);
146 ldmx_log(debug) << " This hit is at " << hit_pos_x << " / "
147 << hit_pos_y << " / " << hit_pos_z << " mm";
148 ldmx_log(debug) << " Ele is projected at " << drift_recoil_x << " / "
149 << drift_recoil_y << " / " << recoil_pos_z - d_z;
150 ldmx_log(debug) << " from " << recoil_pos_x << " / " << recoil_pos_y
151 << " / " << recoil_pos_z << " / " << " mm";
152
153 ldmx_log(debug) << " Ele had momentum of " << recoil_mom_x << " / "
154 << recoil_mom_y << " / " << recoil_mom_z << " MeV";
155 ldmx_log(debug) << " This hit has PE = " << pe
156 << " and dR from ele = " << "is " << d_r << " mm";
157
158 // Dont consider this hit for max PE hit if it's too close to the recoil
159 // electron trajectory
160 if (d_r < dr_from_recoil_max_) {
161 continue;
162 }
163 }
164 num_non_recoil_hits++;
165
166 // Find the maximum PE in the list
167 if (max_pe < pe) {
168 max_pe = pe;
169 max_pe_hit = &hcal_hit;
170 }
171 }
172
173 ldmx_log(info) << "There are " << num_valid_hits << " / " << num_total_hits
174 << " HCal hits read out. " << num_non_recoil_hits
175 << " are not associated with the recoil ele. Total PE of "
176 << total_pe;
177 // If the maximum PE found is below threshold, it passes the veto.
178 bool passes_veto = (max_pe < total_pe_threshold_);
179 ldmx_log(info) << "HCAL veto passed? " << passes_veto;
180
182 result.setVetoResult(passes_veto);
183 result.setMaxPEHit(*max_pe_hit);
184 result.setTotalPE(total_pe);
185 result.setNumValidHits(num_valid_hits);
186
187 // Skimming rules
188 if (!inverse_skim_) {
189 if (passes_veto) {
191 } else {
193 }
194 } else {
195 // Inverse skimming rules
196 if (passes_veto) {
198 } else {
200 }
201 }
202
203 event.add(output_coll_name_, result);
204}
205
206std::vector<float> HcalVetoProcessor::trackProp(const ldmx::Tracks& tracks,
207 ldmx::TrackStateType ts_type,
208 const std::string& ts_title) {
209 // Vector to hold the new track state variables
210 std::vector<float> new_track_states;
211
212 // Return if no tracks
213 if (tracks.empty()) return new_track_states;
214
215 // Otherwise loop on the tracks
216 for (auto& track : tracks) {
217 // Get track state for ts_type
218 auto trk_ts = track.getTrackState(ts_type);
219 // Continue if there's no value
220 if (!trk_ts.has_value()) continue;
221 ldmx::Track::TrackState hcal_track_state = trk_ts.value();
222
223 // Check that the track state is filled
224 if (hcal_track_state.pos_.size() < 3 || hcal_track_state.mom_.size() < 3)
225 continue;
226
227 // pos_ is (x, y, z) in mm (LDMX global); mom_ is (px, py, pz) in MeV
228 new_track_states.push_back(static_cast<float>(hcal_track_state.pos_[0]));
229 new_track_states.push_back(static_cast<float>(hcal_track_state.pos_[1]));
230 new_track_states.push_back(static_cast<float>(hcal_track_state.pos_[2]));
231 new_track_states.push_back(static_cast<float>(hcal_track_state.mom_[0]));
232 new_track_states.push_back(static_cast<float>(hcal_track_state.mom_[1]));
233 new_track_states.push_back(static_cast<float>(hcal_track_state.mom_[2]));
234 break;
235 }
236
237 return new_track_states;
238}
239
240} // namespace hcal
241
#define DECLARE_PRODUCER(CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
Class that defines an HCal sensitive detector.
Processor that determines if an event is vetoed by the Hcal.
Class used to encapsulate the results obtained from HcalVetoProcessor.
void setStorageHint(framework::StorageControl::Hint hint)
Mark the current event as having the given storage control hint from this module_.
Implements an event buffer system for storing event data.
Definition Event.h:40
Class which represents the process under execution.
Definition Process.h:34
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:26
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75
HcalVetoProcessor(const std::string &name, framework::Process &process)
Constructor.
double total_pe_threshold_
Total PE threshold.
float max_time_
Maximum hit time that should be considered by the veto.
void configure(framework::config::Parameters &parameters) override
Configure the processor using the given user specified parameters.
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.
float back_min_pe_
The minimum number of PE in both bars needed for a hit to be considered in double ended readout mode.
void produce(framework::Event &event) override
Run the processor and create a collection of results which indicate if the event passes/fails the Hca...
Stores reconstructed hit information from the HCAL.
Definition HcalHit.h:24
void setSection(int section)
Set the section for this hit.
Definition HcalHit.h:166
void setEnd(int end)
Set the end (0 neg, 1 pos_ side).
Definition HcalHit.h:184
void setToaNeg(double toaNeg)
Set toa of the negative end.
Definition HcalHit.h:208
void clear()
Clear the data in the object.
Definition HcalHit.cxx:9
void setTimeDiff(double timeDiff)
Set time difference (uncorrected)
Definition HcalHit.h:196
void setMinPE(float minpe)
Set the minimum number of photoelectrons estimated for this hit.
Definition HcalHit.h:160
void setToaPos(double toaPos)
Set toa of the positive end.
Definition HcalHit.h:202
void setAmplitudeNeg(double amplitudeNeg)
Set amplitude of the negative end.
Definition HcalHit.h:220
void setStrip(int strip)
Set the strip for this hit.
Definition HcalHit.h:178
void setAmplitudePos(double amplitudePos)
Set amplitude of the positive end.
Definition HcalHit.h:214
void setLayer(int layer)
Set the layer for this hit.
Definition HcalHit.h:172
void setPE(float pe)
Set the number of photoelectrons estimated for this hit.
Definition HcalHit.h:153
Implements detector ids for HCal subdetector.
Definition HcalID.h:19
void setVetoResult(const bool &passes_veto=true)
Sets whether the Hcal veto was passed or not.
void setTotalPE(const float total_PE)
Set the total number of PE.
void setNumValidHits(const float num_valid_hits)
Set the number of valid hits_.
void setMaxPEHit(const ldmx::HcalHit max_PE_hit)
Set the maximum PE hit.
Implementation of a track object.
Definition Track.h:54
constexpr StorageControl::Hint HINT_SHOULD_DROP
storage control hint alias for backwards compatibility
constexpr StorageControl::Hint HINT_SHOULD_KEEP
storage control hint alias for backwards compatibility