LDMX Software
HcalVetoProcessor.cxx
Go to the documentation of this file.
1
9
10namespace hcal {
11
13 framework::Process &process)
14 : Producer(name, process) {}
15
17 total_pe_threshold_ = parameters.get<double>("pe_threshold");
18 max_time_ = parameters.get<double>("max_time");
19 output_coll_name_ = parameters.get<std::string>("output_coll_name");
20 input_hit_coll_name_ = parameters.get<std::string>("input_hit_coll_name");
21 input_hit_pass_name_ = parameters.get<std::string>("input_hit_pass_name");
22 track_pass_name_ = parameters.get<std::string>("track_pass_name");
23
24 // A fake-hit that gets added for the rare case where no hit actually reaches
25 // the maxPE < pe check to avoid producing uninitialized memory
26 //
27 // Default constructed hits have nonsense-but predictable values and are
28 // harder to mistake for real hits
29 default_max_hit_.clear();
30 default_max_hit_.setPE(-9999);
31 default_max_hit_.setMinPE(-9999);
32 default_max_hit_.setSection(-9999);
33 default_max_hit_.setLayer(-9999);
34 default_max_hit_.setStrip(-9999);
35 default_max_hit_.setEnd(-999);
36 default_max_hit_.setTimeDiff(-9999);
37 default_max_hit_.setToaPos(-9999);
38 default_max_hit_.setToaNeg(-9999);
39 default_max_hit_.setAmplitudePos(-9999);
40 default_max_hit_.setAmplitudeNeg(-9999);
41
42 double max_depth = parameters.get<double>("max_depth", 0.);
43 if (max_depth != 0.) {
44 EXCEPTION_RAISE(
45 "InvalidParam",
46 "Earlier versions of the Hcal veto defined a max depth for "
47 "positions which is no longer implemented. Remove the "
48 "parameter (max_depth) from your configuration. See "
49 "https://github.com/LDMX-Software/Hcal/issues/61 for details");
50 }
51 back_min_pe_ = parameters.get<double>("back_min_pe");
52 exclude_recoil_ele_ = parameters.get<bool>("exclude_recoil_ele", false);
53 track_collection_ =
54 parameters.get<std::string>("track_collection", "RecoilTracks");
55 dr_from_recoil_max_ = parameters.get<double>("dr_from_recoil_max", 100);
56 inverse_skim_ = parameters.get<bool>("inverse_skim");
57}
58
60 // Get the collection of sim particles from the event
61 const std::vector<ldmx::HcalHit> hcal_rec_hits =
62 event.getCollection<ldmx::HcalHit>(input_hit_coll_name_,
63 input_hit_pass_name_);
64
65 // Where deos the recoil electron end up in the HCAL?
66 float recoil_pos_x{0.0};
67 float recoil_pos_y{0.0};
68 float recoil_pos_z{-9999.0};
69 float recoil_mom_x{-9999.0};
70 float recoil_mom_y{-9999.0};
71 float recoil_mom_z{-9999.0};
72
73 if (exclude_recoil_ele_) {
74 std::vector<float> recoil_track_states;
75 // Get the recoil track collection
76 auto recoil_tracks{
77 event.getCollection<ldmx::Track>(track_collection_, track_pass_name_)};
78
79 // Use ACTS to propage the recoil track to the end of the magnetic field
80 // This happens to be at the ECAL face
81 ldmx::TrackStateType ts_type = ldmx::TrackStateType::AtECAL;
82 recoil_track_states = trackProp(recoil_tracks, ts_type, "ecal");
83 if (!recoil_track_states.empty()) {
84 recoil_pos_x = recoil_track_states[0];
85 recoil_pos_y = recoil_track_states[1];
86 recoil_pos_z = recoil_track_states[2];
87 recoil_mom_x = recoil_track_states[3];
88 recoil_mom_y = recoil_track_states[4];
89 recoil_mom_z = recoil_track_states[5];
90 }
91 }
92
93 // Loop over all of the Hcal hits and calculate to total photoelectrons
94 // in the event.
95 float total_pe{0.0};
96 float max_pe{-1000};
97 int num_total_hits{0};
98 int num_valid_hits{0};
99 int num_non_recoil_hits{0};
100
101 const ldmx::HcalHit *max_pe_hit{&default_max_hit_};
102 for (const ldmx::HcalHit &hcal_hit : hcal_rec_hits) {
103 num_total_hits++;
104 // If the hit time is outside the readout window, don't consider it.
105 if (hcal_hit.getTime() >= max_time_) {
106 continue;
107 }
108
109 // Get the total PE in the bar
110 float pe = hcal_hit.getPE();
111 // Keep track of the total PE
112 total_pe += pe;
113
114 // Check that both sides of the bar have a PE value above threshold.
115 // If not, don't consider the hit. Double sided readout is only
116 // being used for the back HCal bars. For the side HCal, just
117 // use the maximum PE as before.
118 ldmx::HcalID id(hcal_hit.getID());
119 if ((id.section() == ldmx::HcalID::BACK) &&
120 (hcal_hit.getMinPE() < back_min_pe_))
121 continue;
122
123 num_valid_hits++;
124
125 // Max PE should not be caused by the recoil ele
126 if (exclude_recoil_ele_) {
127 // Get the position of this hit
128 auto hit_pos_x = hcal_hit.getXPos();
129 auto hit_pos_y = hcal_hit.getYPos();
130 auto hit_pos_z = hcal_hit.getZPos();
131 auto d_z = recoil_pos_z - hit_pos_z;
132
133 auto drift_recoil_x =
134 (d_z * (recoil_mom_x / recoil_mom_z)) + recoil_pos_x;
135 auto drift_recoil_y =
136 (d_z * (recoil_mom_y / recoil_mom_z)) + recoil_pos_y;
137 auto dx = drift_recoil_x - hit_pos_x;
138 auto dy = drift_recoil_y - hit_pos_y;
139 auto d_r_squared = dx * dx + dy * dy + d_z * d_z;
140 auto d_r = sqrt(d_r_squared);
141 ldmx_log(debug) << " This hit is at " << hit_pos_x << " / "
142 << hit_pos_y << " / " << hit_pos_z << " mm";
143 ldmx_log(debug) << " Ele is projected at " << drift_recoil_x << " / "
144 << drift_recoil_y << " / " << recoil_pos_z - d_z;
145 ldmx_log(debug) << " from " << recoil_pos_x << " / " << recoil_pos_y
146 << " / " << recoil_pos_z << " / " << " mm";
147
148 ldmx_log(debug) << " Ele had momentum of " << recoil_mom_x << " / "
149 << recoil_mom_y << " / " << recoil_mom_z << " MeV";
150 ldmx_log(debug) << " This hit has PE = " << pe
151 << " and dR from ele = " << "is " << d_r << " mm";
152
153 // Dont consider this hit for max PE hit if it's too close to the recoil
154 // electron trajectory
155 if (d_r < dr_from_recoil_max_) {
156 continue;
157 }
158 }
159 num_non_recoil_hits++;
160
161 // Find the maximum PE in the list
162 if (max_pe < pe) {
163 max_pe = pe;
164 max_pe_hit = &hcal_hit;
165 }
166 }
167
168 ldmx_log(info) << "There are " << num_valid_hits << " / " << num_total_hits
169 << " HCal hits read out. " << num_non_recoil_hits
170 << " are not associated with the recoil ele. Total PE of "
171 << total_pe;
172 // If the maximum PE found is below threshold, it passes the veto.
173 bool passes_veto = (max_pe < total_pe_threshold_);
174 ldmx_log(info) << "HCAL veto passed? " << passes_veto;
175
177 result.setVetoResult(passes_veto);
178 result.setMaxPEHit(*max_pe_hit);
179 result.setTotalPE(total_pe);
180 result.setNumValidHits(num_valid_hits);
181
182 // Skimming rules
183 if (!inverse_skim_) {
184 if (passes_veto) {
186 } else {
188 }
189 } else {
190 // Inverse skimming rules
191 if (passes_veto) {
193 } else {
195 }
196 }
197
198 event.add(output_coll_name_, result);
199}
200
201std::vector<float> HcalVetoProcessor::trackProp(const ldmx::Tracks &tracks,
202 ldmx::TrackStateType ts_type,
203 const std::string &ts_title) {
204 // Vector to hold the new track state variables
205 std::vector<float> new_track_states;
206
207 // Return if no tracks
208 if (tracks.empty()) return new_track_states;
209
210 // Otherwise loop on the tracks
211 for (auto &track : tracks) {
212 // Get track state for ts_type
213 auto trk_ts = track.getTrackState(ts_type);
214 // Continue if there's no value
215 if (!trk_ts.has_value()) continue;
216 ldmx::Track::TrackState &hcal_track_state = trk_ts.value();
217
218 // Check that the track state is filled
219 if (hcal_track_state.params_.size() < 5) continue;
220
221 float track_state_loc0 = static_cast<float>(hcal_track_state.params_[0]);
222 float track_state_loc1 = static_cast<float>(hcal_track_state.params_[1]);
223
224 // param 2 = phi (azimuthal), param 3 = theta (polar)
225 // param 4 = QoP
226 // ACTS (local) to LDMX (global) coordinates: (y_,z_,x_)-> (x_,y_,z_)
227 // convert qop [1/GeV] to p [MeV]
228 double p_track_state = (-1 / hcal_track_state.params_[4]) * 1000;
229 // p * sin(theta) * sin(phi)
230 double recoil_mom_x = p_track_state * sin(hcal_track_state.params_[3]) *
231 sin(hcal_track_state.params_[2]);
232 // p * cos(theta)
233 double recoil_mom_y = p_track_state * cos(hcal_track_state.params_[3]);
234 // p * sin(theta) * cos(phi)
235 double recoil_mom_z = p_track_state * sin(hcal_track_state.params_[3]) *
236 cos(hcal_track_state.params_[2]);
237
238 // Store the new track state variables
239 new_track_states.push_back(track_state_loc0);
240 new_track_states.push_back(track_state_loc1);
241 // z_-position as in the tracking exptrapolation
242 new_track_states.push_back(240.5);
243 new_track_states.push_back(recoil_mom_x);
244 new_track_states.push_back(recoil_mom_y);
245 new_track_states.push_back(recoil_mom_z);
246 break;
247 }
248
249 return new_track_states;
250}
251
252} // namespace hcal
253
#define DECLARE_PRODUCER(CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
Processor that determines if an event is vetoed by the Hcal.
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:42
Class which represents the process under execution.
Definition Process.h:36
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:29
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78
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:53
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