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.getParameter<double>("pe_threshold");
18 max_time_ = parameters.getParameter<double>("max_time");
19 output_coll_name_ = parameters.getParameter<std::string>("output_coll_name");
20 input_hit_coll_name_ =
21 parameters.getParameter<std::string>("input_hit_coll_name");
22 input_hit_pass_name_ =
23 parameters.getParameter<std::string>("input_hit_pass_name");
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.getParameter<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.getParameter<double>("back_min_pe");
52 exclude_recoil_ele_ =
53 parameters.getParameter<bool>("exclude_recoil_ele", false);
54 track_collection_ =
55 parameters.getParameter<std::string>("track_collection", "RecoilTracks");
56 dr_from_recoil_max_ =
57 parameters.getParameter<double>("dr_from_recoil_max", 100);
58 inverse_skim_ = parameters.getParameter<bool>("inverse_skim");
59}
60
62 // Get the collection of sim particles from the event
63 const std::vector<ldmx::HcalHit> hcal_rec_hits =
64 event.getCollection<ldmx::HcalHit>(input_hit_coll_name_,
65 input_hit_pass_name_);
66
67 // Where deos the recoil electron end up in the HCAL?
68 float recoil_pos_x{0.0};
69 float recoil_pos_y{0.0};
70 float recoil_pos_z{-9999.0};
71 float recoil_mom_x{-9999.0};
72 float recoil_mom_y{-9999.0};
73 float recoil_mom_z{-9999.0};
74
75 if (exclude_recoil_ele_) {
76 std::vector<float> recoil_track_states;
77 // Get the recoil track collection
78 auto recoil_tracks{event.getCollection<ldmx::Track>(track_collection_)};
79
80 ldmx::TrackStateType ts_type = ldmx::TrackStateType::AtHCAL;
81 recoil_track_states = trackProp(recoil_tracks, ts_type, "hcal");
82 if (!recoil_track_states.empty()) {
83 recoil_pos_x = recoil_track_states[0];
84 recoil_pos_y = recoil_track_states[1];
85 recoil_pos_z = recoil_track_states[2];
86 recoil_mom_x = recoil_track_states[3];
87 recoil_mom_y = recoil_track_states[4];
88 recoil_mom_z = recoil_track_states[5];
89 }
90 }
91
92 // Loop over all of the Hcal hits and calculate to total photoelectrons
93 // in the event.
94 float total_PE{0.0};
95 float max_PE{-1000};
96 int num_total_hits{0};
97 int num_valid_hits{0};
98 int num_non_recoil_hits{0};
99
100 const ldmx::HcalHit *max_PE_hit{&default_max_hit_};
101 for (const ldmx::HcalHit &hcal_hit : hcal_rec_hits) {
102 num_total_hits++;
103 // If the hit time is outside the readout window, don't consider it.
104 if (hcal_hit.getTime() >= max_time_) {
105 continue;
106 }
107
108 // Get the total PE in the bar
109 float pe = hcal_hit.getPE();
110 // Keep track of the total PE
111 total_PE += pe;
112
113 // Check that both sides of the bar have a PE value above threshold.
114 // If not, don't consider the hit. Double sided readout is only
115 // being used for the back HCal bars. For the side HCal, just
116 // use the maximum PE as before.
117 ldmx::HcalID id(hcal_hit.getID());
118 if ((id.section() == ldmx::HcalID::BACK) &&
119 (hcal_hit.getMinPE() < back_min_PE_))
120 continue;
121
122 num_valid_hits++;
123
124 // Max PE should not be caused by the recoil ele
125 if (exclude_recoil_ele_) {
126 // Get the position of this hit
127 auto hit_pos_x = hcal_hit.getXPos();
128 auto hit_pos_y = hcal_hit.getYPos();
129 auto hit_pos_z = hcal_hit.getZPos();
130 auto dZ = recoil_pos_z - hit_pos_z;
131
132 auto drift_recoil_x = (dZ * (recoil_mom_x / recoil_mom_z)) + recoil_pos_x;
133 auto drift_recoil_y = (dZ * (recoil_mom_y / recoil_mom_z)) + recoil_pos_y;
134 auto dx = drift_recoil_x - hit_pos_x;
135 auto dy = drift_recoil_y - hit_pos_y;
136 auto dR_squared = dx * dx + dy * dy + dZ * dZ;
137 auto dR = sqrt(dR_squared);
138 ldmx_log(debug) << " This hit is at " << hit_pos_x << " / "
139 << hit_pos_y << " / " << hit_pos_z << " mm";
140 ldmx_log(debug) << " Ele is projected at " << drift_recoil_x << " / "
141 << drift_recoil_y << " / " << recoil_pos_z - dZ;
142 ldmx_log(debug) << " from " << recoil_pos_x << " / " << recoil_pos_y
143 << " / " << recoil_pos_z << " / "
144 << " mm";
145
146 ldmx_log(debug) << " Ele had momentum of " << recoil_mom_x << " / "
147 << recoil_mom_y << " / " << recoil_mom_z << " MeV";
148 ldmx_log(debug) << " This hit has PE = " << pe << " and dR from ele = "
149 << "is " << dR << " mm";
150
151 // Dont consider this hit for max PE hit if it's too close to the recoil
152 // electron trajectory
153 if (dR < dr_from_recoil_max_) {
154 continue;
155 }
156 }
157 num_non_recoil_hits++;
158
159 // Find the maximum PE in the list
160 if (max_PE < pe) {
161 max_PE = pe;
162 max_PE_hit = &hcal_hit;
163 }
164 }
165
166 ldmx_log(info) << "There are " << num_valid_hits << " / " << num_total_hits
167 << " HCal hits read out. " << num_non_recoil_hits
168 << " are not associated with the recoil ele. Total PE of "
169 << total_PE;
170 // If the maximum PE found is below threshold, it passes the veto.
171 bool passes_veto = (max_PE < total_PE_threshold_);
172 ldmx_log(info) << "HCAL veto passed? " << passes_veto;
173
175 result.setVetoResult(passes_veto);
176 result.setMaxPEHit(*max_PE_hit);
177 result.setTotalPE(total_PE);
178 result.setNumValidHits(num_valid_hits);
179
180 // Skimming rules
181 if (!inverse_skim_) {
182 if (passes_veto) {
184 } else {
186 }
187 } else {
188 // Inverse skimming rules
189 if (passes_veto) {
191 } else {
193 }
194 }
195
196 event.add(output_coll_name_, result);
197}
198
199std::vector<float> HcalVetoProcessor::trackProp(const ldmx::Tracks &tracks,
200 ldmx::TrackStateType ts_type,
201 const std::string &ts_title) {
202 // Vector to hold the new track state variables
203 std::vector<float> new_track_states;
204
205 // Return if no tracks
206 if (tracks.empty()) return new_track_states;
207
208 // Otherwise loop on the tracks
209 for (auto &track : tracks) {
210 // Get track state for ts_type
211 auto trk_ts = track.getTrackState(ts_type);
212 // Continue if there's no value
213 if (!trk_ts.has_value()) continue;
214 ldmx::Track::TrackState &hcal_track_state = trk_ts.value();
215
216 // Check that the track state is filled
217 if (hcal_track_state.params.size() < 5) continue;
218
219 float track_state_loc0 = static_cast<float>(hcal_track_state.params[0]);
220 float track_state_loc1 = static_cast<float>(hcal_track_state.params[1]);
221
222 // param 2 = phi (azimuthal), param 3 = theta (polar)
223 // param 4 = QoP
224 // ACTS (local) to LDMX (global) coordinates: (y,z,x)-> (x,y,z)
225 // convert qop [1/GeV] to p [MeV]
226 double p_track_state = (-1 / hcal_track_state.params[4]) * 1000;
227 // p * sin(theta) * sin(phi)
228 double recoil_mom_x = p_track_state * sin(hcal_track_state.params[3]) *
229 sin(hcal_track_state.params[2]);
230 // p * cos(theta)
231 double recoil_mom_y = p_track_state * cos(hcal_track_state.params[3]);
232 // p * sin(theta) * cos(phi)
233 double recoil_mom_z = p_track_state * sin(hcal_track_state.params[3]) *
234 cos(hcal_track_state.params[2]);
235
236 // Store the new track state variables
237 new_track_states.push_back(track_state_loc0);
238 new_track_states.push_back(track_state_loc1);
239 // z-position as in the tracking exptrapolation
240 new_track_states.push_back(540.0);
241 new_track_states.push_back(recoil_mom_x);
242 new_track_states.push_back(recoil_mom_y);
243 new_track_states.push_back(recoil_mom_z);
244 break;
245 }
246
247 return new_track_states;
248}
249
250} // namespace hcal
251
252DECLARE_PRODUCER_NS(hcal, HcalVetoProcessor);
#define DECLARE_PRODUCER_NS(NS, 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
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.
void produce(framework::Event &event) override
Run the processor and create a collection of results which indicate if the event passes/fails the Hca...
float back_min_PE_
The minimum number of PE in both bars needed for a hit to be considered in double ended readout mode.
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 Clear()
Clear the data in the object.
Definition HcalHit.cxx:9
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 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_shouldKeep
storage control hint alias for backwards compatibility
constexpr StorageControl::Hint hint_shouldDrop
storage control hint alias for backwards compatibility