14#include "Ecal/EcalReconConditions.h"
15#include "Ecal/Event/EcalHit.h"
19#include "Tools/PulseFitter.h"
25 : Producer(name, process) {}
37 ps.
get<
double>(
"second_order_energy_correction");
48 phase_name_ = ps.
get<std::string>(
"phase_name",
"ecal_digi_phase");
50 auto shape = ps.
get<std::vector<double>>(
"pulse_shape");
51 if (shape.size() != 5) {
52 EXCEPTION_RAISE(
"InvalidConfig",
"pulse_shape needs 5 parameters.");
55 shape[0], shape[1], shape[2], shape[3], shape[4]);
57 EXCEPTION_RAISE(
"InvalidConfig",
"Unknown amplitude_method '" +
59 "', use soi, max or fit.");
67 rng_.seed(rseed.getSeed(
getName() +
"::phase"));
74 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
80 if (geometry.getNumLayers() >
static_cast<int>(
layer_weights_.size())) {
83 "The number of layers in the Ecal geometry (" +
84 std::to_string(geometry.getNumLayers()) +
85 ") exceeds the number of configured layer_weights (" +
87 "). This is likely caused by a mismatch between the geometry "
88 "version and the reconstruction configuration. Please ensure "
89 "that the correct geometry is being used.");
97 std::vector<ldmx::EcalHit> ecal_rec_hits;
112 for (
auto digi : ecal_digis) {
118 auto [x_, y_, z_] = geometry.getPosition(
id);
122 int i_tot = digi.totSampleIndex();
134 auto tot_sample = digi.at(i_tot);
139 charge = (tot_sample.tot() - the_conditions.
totPedestal(
id)) *
146 ldmx_log(trace) <<
"Recon { TOA: " << hit_time <<
" ns } ";
147 ldmx_log(trace) <<
"TOT Mode (sample " << i_tot <<
") -> "
148 << tot_sample.tot() <<
"TDC -> " << charge <<
" fC";
151 ldmx_log(trace) <<
"Recon { TOA: " << hit_time <<
" ns } ";
169 const double pedestal = the_conditions.
adcPedestal(
id);
171 charge = (digi.soi().adcT() - pedestal) * the_conditions.
adcGain(
id);
173 std::vector<short> adc;
174 for (
unsigned int i{0}; i < digi.size(); i++)
175 adc.push_back(
static_cast<short>(digi.at(i).adcT()));
176 int i_max = std::max_element(adc.begin(), adc.end()) - adc.begin();
178 charge = (adc[i_max] - pedestal) * the_conditions.
adcGain(
id);
184 const int n_adc =
static_cast<int>(adc.size());
190 i_soi +
static_cast<int>(std::lround(t0_fixed /
clock_cycle_));
192 const int first = std::clamp(i_peak - 1, 0, n_adc - n);
193 std::vector<short> window(adc.begin() + first,
194 adc.begin() + first + n);
202 : fitter.
fit(window);
208 ldmx_log(trace) <<
"ADC Mode -> " << charge <<
" fC";
223 if (charge <= 0)
continue;
226 double energy_deposited_in_si = num_mips_equivalent *
mip_si_energy_;
228 ldmx_log(trace) <<
" -> " << num_mips_equivalent <<
" equiv MIPs -> "
229 << energy_deposited_in_si <<
" MeV";
232 double reconstructed_energy =
233 (num_mips_equivalent *
236 + energy_deposited_in_si
242 rec_hit.
setID(
id.raw());
250 ecal_rec_hits.push_back(rec_hit);
258 std::set<int> real_hits;
259 for (
auto const& sim_hit : ecal_sim_hits) real_hits.insert(sim_hit.getID());
260 for (
auto& hit : ecal_rec_hits)
261 hit.setNoise(real_hits.find(hit.getID()) == real_hits.end());
Class that translates raw positions of ECal module hits into cells in a hexagonal readout.
Class that defines an ECal detector ID with a cell number.
Class that performs basic ECal digitization.
#define DECLARE_PRODUCER(CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
Class that represents a digitized hit in a calorimeter cell readout by an HGCROC.
Conditions object for random number seeds.
Class which stores simulated calorimeter hit information.
Performs basic ECal reconstruction.
std::string phase_name_
event header float parameter holding the event phase [ns]
double mip_si_energy_
Energy [MeV] deposited by a MIP in Si 0.5mm thick.
std::string sim_hit_coll_name_
simhit collection name
void onNewRun(const ldmx::RunHeader &) override
Seed the phase smearing.
std::string amplitude_method_
ADC mode amplitude: soi, max or fit.
bool fit_fixed_t0_
fit with t0 = event phase + offset, e.g. phase from HCal TOA
double fit_t0_offset_
offset [ns] between the event phase and the pulse t0
double phase_resolution_
Gaussian smearing [ns] of the event phase.
std::vector< double > layer_weights_
Layer Weights to use for this reconstruction.
double second_order_energy_correction_
Second Order Energy Correction to use for this reconstruction.
double charge_per_mip_
Number of electrons generated by average MIP in Si 0.5mm thick.
std::string rec_hit_coll_name_
output hit collection name
EcalRecProducer(const std::string &name, framework::Process &process)
Constructor.
int fit_n_samples_
number of samples in the fit, starting one before the max, <= 0 for all
std::string digi_pass_name_
Digi Pass Name to use as input.
void produce(framework::Event &event) override
Produce EcalHits and put them into the event bus using the EcalDigis as input.
double clock_cycle_
Length of clock cycle [ns].
std::string sim_hit_pass_name_
simhit pass name
void configure(framework::config::Parameters &) override
Grabs configure parameters from the python config file.
std::unique_ptr< ldmx::HgcrocShape > pulse_shape_
HGCROC pulse template, only for amplitude_method fit.
std::string digi_coll_name_
Digi Collection Name to use as input.
Class to wrap around an double table of conditions.
double adcPedestal(const ldmx::EcalID &id) const
get the ADC pedestal
double adcGain(const ldmx::EcalID &id) const
get the ADC gain
double totPedestal(const ldmx::EcalID &id) const
get the TOT pedestal
static const std::string CONDITIONS_NAME
the name of the EcalReconConditions table (must match python registration name)
double totGain(const ldmx::EcalID &id) const
get the TOT gain
const T & getCondition(const std::string &condition_name)
Access a conditions object for the current event.
std::string getName() const
Get the processor name.
Implements an event buffer system for storing event data.
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.
Class which represents the process under execution.
static const std::string CONDITIONS_OBJECT_NAME
Conditions object name.
Class encapsulating parameters for configuring a processor.
const T & get(const std::string &name) const
Retrieve the parameter of the given 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].
Stores reconstructed hit information from the ECAL.
Extension of DetectorID providing access to ECal layers and cell numbers in a hex grid.
Represents a collection of the digi hits readout by an HGCROC.
unsigned int getSampleOfInterestIndex() const
Get index of sample of interest.
Fits a pulse shape to the ADC samples of a single readout channel to extract hit amplitude and time.
FitResult fitFixed(const std::vector< short > &samples, double T) const
Amplitude only fit with the hit time T known, e.g.
FitResult fit(const std::vector< short > &samples) const
Fit the pulse to the given ADC sample vector.
Stores simulated calorimeter hit information.
bool converged
False if no above-pedestal samples found.