LDMX Software
hcal::HcalRecProducer Class Reference

Performs basic HCal reconstruction. More...

#include <HcalRecProducer.h>

Public Member Functions

 HcalRecProducer (const std::string &name, framework::Process &process)
 Constructor.
 
virtual ~HcalRecProducer ()=default
 Destructor.
 
void configure (framework::config::Parameters &) override
 Grabs configure parameters from the python config file.
 
double getTOA (const ldmx::HgcrocDigiCollection::HgcrocDigi digi, double pedestal, unsigned int iSOI) const
 Gets Time of Arrival with respect to the SOI.
 
void produce (framework::Event &event) override
 Produce HcalHits and put them into the event bus using the HcalDigis as input.
 
- Public Member Functions inherited from framework::Producer
 Producer (const std::string &name, Process &process)
 Class constructor.
 
virtual void process (Event &event) final
 Processing an event for a Producer is calling produce.
 
- Public Member Functions inherited from framework::EventProcessor
 DECLARE_FACTORY (EventProcessor, EventProcessor *, const std::string &, Process &)
 declare that we have a factory for this class
 
 EventProcessor (const std::string &name, Process &process)
 Class constructor.
 
virtual ~EventProcessor ()=default
 Class destructor.
 
virtual void beforeNewRun (ldmx::RunHeader &run_header)
 Callback for Producers to add parameters to the run header before conditions are initialized.
 
virtual void onNewRun (const ldmx::RunHeader &run_header)
 Callback for the EventProcessor to take any necessary action when the run being processed changes.
 
virtual void onFileOpen (EventFile &event_file)
 Callback for the EventProcessor to take any necessary action when a new event input ROOT file is opened.
 
virtual void onFileClose (EventFile &event_file)
 Callback for the EventProcessor to take any necessary action when a event input ROOT file is closed.
 
virtual void onProcessStart ()
 Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.
 
virtual void onProcessEnd ()
 Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.
 
template<class T >
const T & getCondition (const std::string &condition_name)
 Access a conditions object for the current event.
 
TDirectory * getHistoDirectory ()
 Access/create a directory in the histogram file for this event processor to create histograms and analysis tuples.
 
void setStorageHint (framework::StorageControl::Hint hint)
 Mark the current event as having the given storage control hint from this module_.
 
void setStorageHint (framework::StorageControl::Hint hint, const std::string &purposeString)
 Mark the current event as having the given storage control hint from this module and the given purpose string.
 
int getLogFrequency () const
 Get the current logging frequency from the process.
 
int getRunNumber () const
 Get the run number from the process.
 
std::string getName () const
 Get the processor name.
 
void createHistograms (const std::vector< framework::config::Parameters > &histos)
 Internal function which is used to create histograms passed from the python configuration @parma histos vector of Parameters that configure histograms to create.
 

Private Attributes

std::string input_coll_name_
 Digi Collection Name to use as input.
 
std::string input_pass_name_
 Digi Pass Name to use as input.
 
std::string sim_hit_coll_name_
 simhit collection name
 
std::string sim_hit_pass_name_
 simhit pass name
 
std::string rec_hit_coll_name_
 output hit collection name
 
double mip_energy_
 Energy [MeV] deposited by a MIP.
 
double pe_per_mip_
 PEs per MIP.
 
double clock_cycle_
 Length of clock cycle [ns].
 
double voltage_per_mip_
 Voltage by average MIP.
 
double attlength_
 Strip attenuation length [m].
 
TF1 pulse_func_
 Pulse function.
 
TGraph correction_ampl_
 Correction to the pulse's measured amplitude at the peak.
 
TGraph correction_toa_
 Correction to the measured TOA relative to the peak.
 
double min_ampl_fraction_
 Minimum amplitude fraction to apply amplitude correction.
 
double min_ampl_
 Minimum amplitude to apply TOA correction.
 
int n_adcs_
 Depth of ADC buffer.
 
double rate_up_slope_
 Rate of Up Slope in Pulse Shape [1/ns].
 
double time_up_slope_
 Time of Up Slope relative to Pulse Shape Fit [ns].
 
double rate_dn_slope_
 Rate of Down Slope in Pulse Shape [1/ns].
 
double time_dn_slope_
 Time of Down Slope relative to Pulse Shape Fit [ns].
 
double time_peak_
 Time of Peak relative to pulse shape fit [ns].
 

Additional Inherited Members

- Protected Member Functions inherited from framework::EventProcessor
void abortEvent ()
 Abort the event immediately.
 
- Protected Attributes inherited from framework::EventProcessor
HistogramPool histograms_
 helper object for making and filling histograms
 
NtupleManager & ntuple_ {NtupleManager::getInstance()}
 Manager for any ntuples.
 
logging::logger the_log_
 The logger for this EventProcessor.
 

Detailed Description

Performs basic HCal reconstruction.

Reconstruction is done from the HcalDigi samples. Some hard-coded parameters are used for position and energy calculation.

Definition at line 34 of file HcalRecProducer.h.

Constructor & Destructor Documentation

◆ HcalRecProducer()

hcal::HcalRecProducer::HcalRecProducer ( const std::string & name,
framework::Process & process )

Constructor.

Definition at line 22 of file HcalRecProducer.cxx.

24 : Producer(name, process) {}
Producer(const std::string &name, Process &process)
Class constructor.
virtual void process(Event &event) final
Processing an event for a Producer is calling produce.

Member Function Documentation

◆ configure()

void hcal::HcalRecProducer::configure ( framework::config::Parameters & ps)
overridevirtual

Grabs configure parameters from the python config file.

Reimplemented from framework::EventProcessor.

Definition at line 26 of file HcalRecProducer.cxx.

26 {
27 // collection names
28 input_coll_name_ = ps.get<std::string>("input_coll_name");
29 input_pass_name_ = ps.get<std::string>("input_pass_name");
30 sim_hit_coll_name_ = ps.get<std::string>("sim_hit_coll_name");
31 sim_hit_pass_name_ = ps.get<std::string>("sim_hit_pass_name");
32 rec_hit_coll_name_ = ps.get<std::string>("rec_hit_coll_name");
33 // parameters
34 mip_energy_ = ps.get<double>("mip_energy");
35 pe_per_mip_ = ps.get<double>("pe_per_mip");
36 clock_cycle_ = ps.get<double>("clock_cycle");
37 voltage_per_mip_ = ps.get<double>("voltage_per_mip");
38 attlength_ = ps.get<double>("attenuation_length");
39 n_adcs_ = ps.get<int>("n_adcs");
40
41 // configuring corrections graphs derived on the fly
42 // TODO: maybe we should save these as a graph instead?
43 rate_up_slope_ = ps.get<double>("rate_up_slope");
44 time_up_slope_ = ps.get<double>("time_up_slope");
45 rate_dn_slope_ = ps.get<double>("rate_dn_slope");
46 time_dn_slope_ = ps.get<double>("time_dn_slope");
47 time_peak_ = ps.get<double>("time_peak");
49 TF1("pulseFunc",
50 "[0]*((1.0+exp([1]*(-[2]+[3])))*(1.0+exp([5]*(-[6]+[3]))))/"
51 "((1.0+exp([1]*(x-[2]+[3]-[4])))*(1.0+exp([5]*(x-[6]+[3]-[4]))))",
52 (double)n_adcs_ * clock_cycle_ * -1, (double)n_adcs_ * clock_cycle_);
53 pulse_func_.FixParameter(1, rate_up_slope_);
54 pulse_func_.FixParameter(2, time_up_slope_);
55 pulse_func_.FixParameter(3, time_peak_);
56 pulse_func_.FixParameter(5, rate_dn_slope_);
57 pulse_func_.FixParameter(6, time_dn_slope_);
58 pulse_func_.FixParameter(4, 0);
59 pulse_func_.FixParameter(0, 1);
60
61 // build amplitude correction (Ampl[t-1]/Ampl[t]) with pulse-shape
62 int n = 0;
63 for (double t = -clock_cycle_; t < clock_cycle_; t += 0.01) {
64 double ampl_t = pulse_func_.Eval(t);
65 double ampl_tm1 = pulse_func_.Eval(t - clock_cycle_);
66 if (ampl_tm1 > ampl_t) continue;
67 correction_ampl_.SetPoint(n, ampl_tm1 / ampl_t, ampl_t);
68 if (n == 0) min_ampl_fraction_ = ampl_tm1 / ampl_t;
69 n++;
70 }
71
72 // build TOA timewalk correction with pulse-shape
73 double toa_threshold = ps.get<double>("avg_toa_threshold");
74 double gain = ps.get<double>("avg_gain");
75 double pedestal = ps.get<double>("avg_pedestal");
76 n = 0;
77 for (double ampl = toa_threshold + 0.1; ampl < 10000; ampl += 0.01) {
78 pulse_func_.FixParameter(0, ampl);
79 double ampl_t = gain * pedestal + pulse_func_.Eval(0);
80 double toa = fabs(pulse_func_.GetX(toa_threshold,
81 (double)n_adcs_ * clock_cycle_ * -1,
82 (double)n_adcs_ * clock_cycle_));
83 correction_toa_.SetPoint(n, ampl_t, toa);
84 if (n == 0) min_ampl_ = ampl_t;
85 n++;
86 }
87 correction_toa_.SetBit(TGraph::kIsSortedX);
88}
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75
double min_ampl_
Minimum amplitude to apply TOA correction.
double rate_dn_slope_
Rate of Down Slope in Pulse Shape [1/ns].
double time_dn_slope_
Time of Down Slope relative to Pulse Shape Fit [ns].
double clock_cycle_
Length of clock cycle [ns].
double voltage_per_mip_
Voltage by average MIP.
std::string rec_hit_coll_name_
output hit collection name
double time_peak_
Time of Peak relative to pulse shape fit [ns].
TGraph correction_toa_
Correction to the measured TOA relative to the peak.
int n_adcs_
Depth of ADC buffer.
std::string input_pass_name_
Digi Pass Name to use as input.
std::string sim_hit_coll_name_
simhit collection name
double rate_up_slope_
Rate of Up Slope in Pulse Shape [1/ns].
double mip_energy_
Energy [MeV] deposited by a MIP.
double attlength_
Strip attenuation length [m].
TGraph correction_ampl_
Correction to the pulse's measured amplitude at the peak.
std::string input_coll_name_
Digi Collection Name to use as input.
double time_up_slope_
Time of Up Slope relative to Pulse Shape Fit [ns].
TF1 pulse_func_
Pulse function.
double pe_per_mip_
PEs per MIP.
std::string sim_hit_pass_name_
simhit pass name
double min_ampl_fraction_
Minimum amplitude fraction to apply amplitude correction.

References attlength_, clock_cycle_, correction_ampl_, correction_toa_, framework::config::Parameters::get(), input_coll_name_, input_pass_name_, min_ampl_, min_ampl_fraction_, mip_energy_, n_adcs_, pe_per_mip_, pulse_func_, rate_dn_slope_, rate_up_slope_, rec_hit_coll_name_, sim_hit_coll_name_, sim_hit_pass_name_, time_dn_slope_, time_peak_, time_up_slope_, and voltage_per_mip_.

◆ getTOA()

double hcal::HcalRecProducer::getTOA ( const ldmx::HgcrocDigiCollection::HgcrocDigi digi,
double pedestal,
unsigned int iSOI ) const

Gets Time of Arrival with respect to the SOI.

Definition at line 90 of file HcalRecProducer.cxx.

92 {
93 // get toa relative to the startBX
94 double toa_rel_start_bx(0.), max_meas{0.};
95 int toa_sample(0), max_sample(0), i_adc(0);
96 for (int i_sample{0}; i_sample < digi.size(); i_sample++) {
97 auto sample{digi.at(i_sample)};
98 if (sample.toa() > 0) {
99 toa_rel_start_bx = sample.toa() * (clock_cycle_ / 1024); // ns
100 // find in which ADC sample the TOA was taken
101 toa_sample = i_adc;
102 }
103 if ((sample.adcT() - pedestal) > max_meas) {
104 max_meas = (sample.adcT() - pedestal);
105 max_sample = i_adc;
106 }
107 i_adc++;
108 }
109
110 // time w.r.t to the peak
111 double toa = (max_sample - toa_sample) * clock_cycle_ - toa_rel_start_bx;
112
113 // time w.r.t to the SOI
114 toa += (static_cast<int>(iSOI) - max_sample) * clock_cycle_;
115
116 return toa;
117}
HgcrocDigiCollection::Sample at(unsigned int i_sample) const
get the sample at a specific index in the digi

References ldmx::HgcrocDigiCollection::HgcrocDigi::at(), and clock_cycle_.

Referenced by produce().

◆ produce()

void hcal::HcalRecProducer::produce ( framework::Event & event)
overridevirtual

Produce HcalHits and put them into the event bus using the HcalDigis as input.

This function unfolds the digi samples taken by the HGC ROC and reconstructs their energy using knowledge of how the chip operates and the position using HcalGeometry.

Simple calculation of sampling fraction: Thickness per layer: scintillator (0.2cm) + steel (0.25cm) Radiation length and nuclear interaction length: scintillator: X0 = 41.31cm, Lambda = 77.07cm https://pdg.lbl.gov/2017/AtomicNuclearProperties/HTML/polystyrene.html steel X0 = 1.757cm, Lambda = 16.77cm https://pdg.lbl.gov/2012/AtomicNuclearProperties/HTML_PAGES/026.html Prob of EM interaction (e.g. pi0): thickness/X0*100 = (0.2/41.31)/ ((0.2/41.31)

  • (0.25/1.757)) ~ 3.3% Prob of Had interaction (e.g. pi+/pi-): = (0.2/77.07)/ ((0.2/77.07) + (0.25/16.77)) ~ 15% Then e.g. for neutron assuming 1/3 pi0 and 2/3 pi+/- composition: sampling fraction ~ (1/3)*3.3.% + (2/3)*15% ~ 11% energy of neutron = energy_deposited / 0.11;

    NOTE: For now, sampling fraction is not applied.

Implements framework::Producer.

Definition at line 119 of file HcalRecProducer.cxx.

119 {
120 // get the Hcal Geometry
121 const auto& hcal_geometry = getCondition<ldmx::HcalGeometry>(
123
124 // get the reconstruction parameters
125 const auto& the_conditions{
127
128 std::vector<ldmx::HcalHit> hcal_rec_hits;
129 auto hcal_digis = event.getObject<ldmx::HgcrocDigiCollection>(
131 int num_digi_hits = hcal_digis.getNumDigis();
132
133 // get sample of interest index
134 unsigned int i_soi = hcal_digis.getSampleOfInterestIndex();
135
136 // loop through digis
137 int i_digi = 0;
138 while (i_digi < num_digi_hits) {
139 auto digi_posend = hcal_digis.getDigi(i_digi);
140
141 // track readout mode for this hit (1 = ADC, 0 = TOT)
142 bool is_adc_mode = false;
143
144 // ID from first digi sample (which should be in positive end)
145 ldmx::HcalDigiID id_posend(digi_posend.id());
146 ldmx::HcalID id(id_posend.section(), id_posend.layer(), id_posend.strip());
147
148 // position from ID
149 auto position = hcal_geometry.getStripCenterPosition(id);
150 double half_total_width =
151 hcal_geometry.getHalfTotalWidth(id.section(), id.layer());
152 double ecal_dx = hcal_geometry.getEcalDx();
153 double ecal_dy = hcal_geometry.getEcalDy();
154
155 // compute distance to the end of the bar
156 // for back Hcal, we take the half of the bar
157 // for side Hcal, we take the length of the bar (2*half-width)-Ecal_dxy as
158 // an approximation
159 float distance_posend, distance_negend, distance_ecal;
160 const bool explicit_layout{hcal_geometry.hasExplicitLayout()};
161 if (explicit_layout) {
162 distance_posend = hcal_geometry.getScintillatorLength(id) / 2;
163 distance_negend = distance_posend;
164 } else if (id.section() == ldmx::HcalID::HcalSection::BACK) {
165 distance_posend = half_total_width;
166 distance_negend = half_total_width;
167 } else {
168 if ((id.section() == ldmx::HcalID::HcalSection::TOP) ||
169 (id.section() == ldmx::HcalID::HcalSection::BOTTOM)) {
170 distance_ecal = ecal_dx;
171 } else {
172 distance_ecal = ecal_dy;
173 }
174 distance_posend = 2 * half_total_width - distance_ecal / 2.;
175 distance_negend = distance_ecal / 2.;
176 }
177
178 // get the estimated voltage and time from digi samples
179 double voltage(0.);
180 double voltage_min(0.);
181 double hit_time(0.);
182
183 double ampl_t(0.);
184 double ampl_t_posend(0.), ampl_tm1_posend(0.);
185 double ampl_t_negend(0.), ampl_tm1_negend(0.);
186
187 // Check if the bar is oriented in X or Y
188 const auto orientation{hcal_geometry.getScintillatorOrientation(id)};
189 int orientation_int = static_cast<int>(orientation);
190
191 // double readout
192 if (hcal_geometry.isDoubleEnded(id.section())) {
193 auto digi_negend = hcal_digis.getDigi(i_digi + 1);
194 ldmx::HcalDigiID id_negend(digi_negend.id());
195
196 double voltage_posend, voltage_negend;
197 // Check if in TOT mode
198 if (digi_posend.isTOT()) {
199 is_adc_mode = false;
200 voltage_posend =
201 (digi_posend.tot() - the_conditions.totCalib(id_posend, 0)) *
202 the_conditions.totCalib(id_posend, 1);
203 voltage_negend =
204 (digi_negend.tot() - the_conditions.totCalib(id_negend, 0)) *
205 the_conditions.totCalib(id_negend, 1);
206 } // end TOT mode, go to ADC mode
207 else {
208 is_adc_mode = true;
209 ampl_t_posend =
210 digi_posend.soi().adcT() - the_conditions.adcPedestal(id_posend);
211 ampl_tm1_posend =
212 digi_posend.soi().adcTm1() - the_conditions.adcPedestal(id_posend);
213 ampl_t_negend =
214 digi_negend.soi().adcT() - the_conditions.adcPedestal(id_negend);
215 ampl_tm1_negend =
216 digi_negend.soi().adcTm1() - the_conditions.adcPedestal(id_negend);
217
218 // correct amplitude (amplitude fractions from both ends need to be
219 // above the boundary of the correction)
220 if (ampl_tm1_posend / ampl_t_posend > min_ampl_fraction_ &&
221 ampl_tm1_negend / ampl_t_negend > min_ampl_fraction_) {
222 ampl_t_posend *=
223 correction_ampl_.Eval(ampl_tm1_posend / ampl_t_posend);
224 ampl_t_negend *=
225 correction_ampl_.Eval(ampl_tm1_negend / ampl_t_negend);
226 }
227
228 // set voltage
229 voltage_posend = ampl_t_posend * the_conditions.adcGain(id_posend, 0);
230 voltage_negend = ampl_t_negend * the_conditions.adcGain(id_negend, 0);
231 } // end ADC mode
232
233 // get TOA
234 double toa_posend =
235 getTOA(digi_posend, the_conditions.adcPedestal(id_posend), i_soi);
236 double toa_negend =
237 getTOA(digi_negend, the_conditions.adcPedestal(id_negend), i_soi);
238
239 // get sign of position along the bar
240 int position_bar_sign = (toa_posend - toa_negend) > 0 ? 1 : -1;
241
242 // correct TOA
243 // amplitudes from both ends need to be above the boundary of the
244 // correction otherwise, one TOA gets corrected and the other does not,
245 // which results in a large TOA difference and an out-of-bounds position
246 if (ampl_t_posend > min_ampl_ && ampl_t_negend > min_ampl_) {
247 toa_posend = correction_toa_.Eval(ampl_t_posend) - toa_posend;
248 toa_negend = correction_toa_.Eval(ampl_t_negend) - toa_negend;
249 }
250
251 // get x(y) coordinate from TOA measurement = (dt*v/2)
252 // if time_posend < time_negend: position is positive
253 // velocity of light in polystyrene, n = 1.6 = c/v
254 double v = 299.792 / 1.6;
255 double position_bar =
256 position_bar_sign * fabs(toa_posend - toa_negend) * v / 2;
257 // keep the hit on the bar
258 if (explicit_layout) {
259 const double half_length{distance_posend};
260 position_bar = std::clamp(position_bar, -half_length, half_length);
261 }
262
263 // reverse voltage attenuation
264 // if position along the bar is positive, then the positive end will have
265 // less attenuation than the negative end
266 // NOTE: For now, reverse attenuation is not applied to the energy
267 // deposited since both ends of the bar are summed.
268 double att_posend =
269 exp(-1. * ((distance_posend - position_bar) / 1000.) / attlength_);
270 double att_negend =
271 exp(-1. * ((distance_negend + position_bar) / 1000.) / attlength_);
272
273 // set voltage as the sum of both bars
274 voltage = (voltage_posend + voltage_negend);
275 voltage_min = std::min(voltage_posend, voltage_negend);
276
277 // set amplitude as the average of both bars (reverse attenuated)
278 ampl_t = (ampl_t_posend / att_posend + ampl_t_negend / att_negend) / 2;
279
280 // set position along the bar, offset from the strip center if explicit
281 if (orientation ==
282 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
283 position.SetX(explicit_layout ? position.X() + position_bar
284 : position_bar);
285 } else {
286 position.SetY(explicit_layout ? position.Y() + position_bar
287 : position_bar);
288 }
289
290 // set hit time
291 // TODO: does this need to revert shift because of propagation of light in
292 // polysterene?
293 hit_time = fabs(toa_posend + toa_negend) / 2; // ns
294
295 i_digi += 2;
296 } // end double readout loop
297 else { // single readout
298 double voltage_i;
299 // Check if in TOT mode (for single-ended readout)
300 if (digi_posend.isTOT()) {
301 is_adc_mode = false;
302 // TOT - number of clock ticks that pulse was over threshold
303 // this is related to the amplitude of the pulse approximately through a
304 // linear drain rate the amplitude of the pulse is related to the energy
305 // deposited
306
307 // convert the time over threshold into a total energy deposited in the
308 // bar (time over threshold [ns] - pedestal) * gain
309
310 voltage_i = (digi_posend.tot() - the_conditions.totCalib(id_posend)) *
311 the_conditions.totCalib(id_posend);
312
313 } // end TOT mode, go to ADC mode (for single-ended readout)
314 else {
315 is_adc_mode = true;
316 // ADC mode of readout
317 // ADC - voltage measurement at a specific time of the pulse
318 ampl_t_posend =
319 digi_posend.soi().adcT() - the_conditions.adcPedestal(id_posend);
320 ampl_tm1_posend =
321 digi_posend.soi().adcTm1() - the_conditions.adcPedestal(id_posend);
322 voltage_i = ampl_t_posend * the_conditions.adcGain(id_posend);
323 }
324
325 // reverse voltage attenuation
326 // for now, assume that position along the bar is the half_total_width
327 double distance_end =
328 id_posend.isNegativeEnd() ? distance_negend : distance_posend;
329 double att = exp(
330 -1. *
331 ((distance_end - (explicit_layout ? 0. : fabs(half_total_width))) /
332 1000.) /
333 attlength_);
334
335 // set voltage
336 voltage = voltage_i;
337 voltage_min = voltage_i;
338
339 // set amplitude (reverse attenuated)
340 ampl_t = ampl_t_posend / att;
341
342 // get TOA
343 double toa =
344 getTOA(digi_posend, the_conditions.adcPedestal(id_posend), i_soi);
345
346 // correct TOA
347 toa = correction_toa_.Eval(ampl_t) - toa;
348
349 // set hit time
350 hit_time = toa; // ns
351
352 i_digi++;
353 } // end single readout loop
354
355 double num_mips_equivalent = voltage / voltage_per_mip_;
356 double energy_deposited = num_mips_equivalent * mip_energy_;
357
358 // reconstructed energy in the layer (approximate)
359 // TODO: need to incorporate corrections if necessary
376 double reconstructed_energy = energy_deposited;
377
378 int pe_s = num_mips_equivalent * pe_per_mip_;
379 int min_pe_s = (voltage_min / voltage_per_mip_) * pe_per_mip_;
380
381 // copy over information to rec hit structure in new collection
382 ldmx::HcalHit rec_hit;
383 rec_hit.setID(id.raw());
384 rec_hit.setXPos(position.X());
385 rec_hit.setYPos(position.Y());
386 rec_hit.setZPos(position.Z());
387 rec_hit.setSection(id.section());
388 rec_hit.setStrip(id.strip());
389 rec_hit.setLayer(id.layer());
390 rec_hit.setPE(pe_s);
391 rec_hit.setMinPE(min_pe_s);
392 rec_hit.setIsADC(is_adc_mode ? 1 : 0);
393 rec_hit.setAmplitude((ampl_t / voltage_per_mip_) * mip_energy_);
394 rec_hit.setEnergy(reconstructed_energy);
395 rec_hit.setTime(hit_time);
396 rec_hit.setOrientation(orientation_int);
397 hcal_rec_hits.push_back(rec_hit);
398 } // end of digi loop
399
400 // mark noise hits if sim hits are available
402 // hcal sim hits_ exist ==> label which hits_ are real and which are pure
403 // noise
404 auto hcal_sim_hits{event.getCollection<ldmx::SimCalorimeterHit>(
406 std::set<int> real_hits;
407 for (auto const& sim_hit : hcal_sim_hits) real_hits.insert(sim_hit.getID());
408 for (auto& hit : hcal_rec_hits)
409 hit.setNoise(real_hits.find(hit.getID()) == real_hits.end());
410 }
411
412 // add collection to event bus
413 event.add(rec_hit_coll_name_, hcal_rec_hits);
414}
const T & getCondition(const std::string &condition_name)
Access a conditions object for the current event.
bool exists(const std::string &name, const std::string &passName, bool unique=true) const
Check for the existence of an object or collection with the given name and pass name in the event.
Definition Event.cxx:107
double getTOA(const ldmx::HgcrocDigiCollection::HgcrocDigi digi, double pedestal, unsigned int iSOI) const
Gets Time of Arrival with respect to the SOI.
static const std::string CONDITIONS_NAME
the name of the HcalReconConditions table (must match python registration name)
void setYPos(float ypos)
Set the Y position of the hit [mm].
void setID(int id)
Set the detector ID.
void setZPos(float zpos)
Set the Z position of the hit [mm].
void setXPos(float xpos)
Set the X position of the hit [mm].
void setTime(float time)
Set the time of the hit [ns].
void setAmplitude(float amplitude)
Set the amplitude of the hit, which is proportional to the signal in the calorimeter cell without sam...
void setEnergy(float energy)
Set the calorimetric energy of the hit, corrected for sampling factors [MeV].
Extension of HcalAbstractID providing access to HCal digi information.
Definition HcalDigiID.h:13
static constexpr const char * CONDITIONS_OBJECT_NAME
Conditions object: The name of the python configuration calling this class (Hcal/python/HcalGeometry....
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 setIsADC(int isADC)
Set if the hit is reconstructed using ADC.
Definition HcalHit.h:190
void setMinPE(float minpe)
Set the minimum number of photoelectrons estimated for this hit.
Definition HcalHit.h:160
void setOrientation(int orientation)
Set if the bar is orientied in X / Y / Z meanig 0 / 1 / 2, respectively.
Definition HcalHit.h:234
void setStrip(int strip)
Set the strip for this hit.
Definition HcalHit.h:178
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
Represents a collection of the digi hits readout by an HGCROC.
unsigned int getNumDigis() const
Get total number of digis.
Stores simulated calorimeter hit information.

References attlength_, hcal::HcalReconConditions::CONDITIONS_NAME, ldmx::HcalGeometry::CONDITIONS_OBJECT_NAME, correction_ampl_, correction_toa_, framework::Event::exists(), framework::EventProcessor::getCondition(), ldmx::HgcrocDigiCollection::getNumDigis(), getTOA(), input_coll_name_, input_pass_name_, ldmx::HcalDigiID::isNegativeEnd(), ldmx::HcalDigiID::layer(), min_ampl_, min_ampl_fraction_, mip_energy_, pe_per_mip_, rec_hit_coll_name_, ldmx::HcalDigiID::section(), ldmx::CalorimeterHit::setAmplitude(), ldmx::CalorimeterHit::setEnergy(), ldmx::CalorimeterHit::setID(), ldmx::HcalHit::setIsADC(), ldmx::HcalHit::setLayer(), ldmx::HcalHit::setMinPE(), ldmx::HcalHit::setOrientation(), ldmx::HcalHit::setPE(), ldmx::HcalHit::setSection(), ldmx::HcalHit::setStrip(), ldmx::CalorimeterHit::setTime(), ldmx::CalorimeterHit::setXPos(), ldmx::CalorimeterHit::setYPos(), ldmx::CalorimeterHit::setZPos(), sim_hit_coll_name_, sim_hit_pass_name_, ldmx::HcalDigiID::strip(), and voltage_per_mip_.

Member Data Documentation

◆ attlength_

double hcal::HcalRecProducer::attlength_
private

Strip attenuation length [m].

Definition at line 96 of file HcalRecProducer.h.

Referenced by configure(), and produce().

◆ clock_cycle_

double hcal::HcalRecProducer::clock_cycle_
private

Length of clock cycle [ns].

Definition at line 90 of file HcalRecProducer.h.

Referenced by configure(), and getTOA().

◆ correction_ampl_

TGraph hcal::HcalRecProducer::correction_ampl_
mutableprivate

Correction to the pulse's measured amplitude at the peak.

The correction is calculated by comparing the amplitude at the sample time (T) over its correct value (1.0) with the ratio between sample T and sample T+25ns.

Definition at line 107 of file HcalRecProducer.h.

Referenced by configure(), and produce().

◆ correction_toa_

TGraph hcal::HcalRecProducer::correction_toa_
mutableprivate

Correction to the measured TOA relative to the peak.

This corrects for the time-walk effect where the time that the front edge of the pulse crosses the TOA threshold walks higher in time as the pulse's amplitude gets smaller. The correction is calculated by comparing the TOA measured relative to the peak (i.e. the time at which the pulse crosses the TOA threshold) with the amplitude at the sample time (T) over its correct value (1.0).

Definition at line 118 of file HcalRecProducer.h.

Referenced by configure(), and produce().

◆ input_coll_name_

std::string hcal::HcalRecProducer::input_coll_name_
private

Digi Collection Name to use as input.

Definition at line 69 of file HcalRecProducer.h.

Referenced by configure(), and produce().

◆ input_pass_name_

std::string hcal::HcalRecProducer::input_pass_name_
private

Digi Pass Name to use as input.

Definition at line 72 of file HcalRecProducer.h.

Referenced by configure(), and produce().

◆ min_ampl_

double hcal::HcalRecProducer::min_ampl_
private

Minimum amplitude to apply TOA correction.

Definition at line 124 of file HcalRecProducer.h.

Referenced by configure(), and produce().

◆ min_ampl_fraction_

double hcal::HcalRecProducer::min_ampl_fraction_
private

Minimum amplitude fraction to apply amplitude correction.

Definition at line 121 of file HcalRecProducer.h.

Referenced by configure(), and produce().

◆ mip_energy_

double hcal::HcalRecProducer::mip_energy_
private

Energy [MeV] deposited by a MIP.

Definition at line 84 of file HcalRecProducer.h.

Referenced by configure(), and produce().

◆ n_adcs_

int hcal::HcalRecProducer::n_adcs_
private

Depth of ADC buffer.

Definition at line 127 of file HcalRecProducer.h.

Referenced by configure().

◆ pe_per_mip_

double hcal::HcalRecProducer::pe_per_mip_
private

PEs per MIP.

Definition at line 87 of file HcalRecProducer.h.

Referenced by configure(), and produce().

◆ pulse_func_

TF1 hcal::HcalRecProducer::pulse_func_
mutableprivate

Pulse function.

Definition at line 99 of file HcalRecProducer.h.

Referenced by configure().

◆ rate_dn_slope_

double hcal::HcalRecProducer::rate_dn_slope_
private

Rate of Down Slope in Pulse Shape [1/ns].

Definition at line 136 of file HcalRecProducer.h.

Referenced by configure().

◆ rate_up_slope_

double hcal::HcalRecProducer::rate_up_slope_
private

Rate of Up Slope in Pulse Shape [1/ns].

Definition at line 130 of file HcalRecProducer.h.

Referenced by configure().

◆ rec_hit_coll_name_

std::string hcal::HcalRecProducer::rec_hit_coll_name_
private

output hit collection name

Definition at line 81 of file HcalRecProducer.h.

Referenced by configure(), and produce().

◆ sim_hit_coll_name_

std::string hcal::HcalRecProducer::sim_hit_coll_name_
private

simhit collection name

Definition at line 75 of file HcalRecProducer.h.

Referenced by configure(), and produce().

◆ sim_hit_pass_name_

std::string hcal::HcalRecProducer::sim_hit_pass_name_
private

simhit pass name

Definition at line 78 of file HcalRecProducer.h.

Referenced by configure(), and produce().

◆ time_dn_slope_

double hcal::HcalRecProducer::time_dn_slope_
private

Time of Down Slope relative to Pulse Shape Fit [ns].

Definition at line 139 of file HcalRecProducer.h.

Referenced by configure().

◆ time_peak_

double hcal::HcalRecProducer::time_peak_
private

Time of Peak relative to pulse shape fit [ns].

Definition at line 142 of file HcalRecProducer.h.

Referenced by configure().

◆ time_up_slope_

double hcal::HcalRecProducer::time_up_slope_
private

Time of Up Slope relative to Pulse Shape Fit [ns].

Definition at line 133 of file HcalRecProducer.h.

Referenced by configure().

◆ voltage_per_mip_

double hcal::HcalRecProducer::voltage_per_mip_
private

Voltage by average MIP.

Definition at line 93 of file HcalRecProducer.h.

Referenced by configure(), and produce().


The documentation for this class was generated from the following files: