2#include "Tools/HgcrocEmulator.h"
29 "[0]*((1.0+exp([1]*(-[2]+[3])))*(1.0+exp([5]*(-[6]+[3]))))/"
30 "((1.0+exp([1]*(x-[2]+[3]-[4])))*(1.0+exp([5]*(x-[6]+[3]-[4]))))",
47 std::vector<std::pair<double, double>>& arriving_pulses,
48 std::vector<ldmx::HgcrocDigiCollection::Sample>& digiToAdd)
const {
54 double pad_capacitance =
getCondition(channelID,
"PAD_CAPACITANCE");
57 double toa_threshold =
getCondition(channelID,
"TOA_THRESHOLD");
58 double tot_threshold =
getCondition(channelID,
"TOT_THRESHOLD");
63 double drain_rate =
getCondition(channelID,
"DRAIN_RATE");
65 int readout_threshold = int(readout_threshold_float);
70 arriving_pulses.begin(), arriving_pulses.end(),
71 [](
const std::pair<double, double>& a,
72 const std::pair<double, double>& b) { return a.first > b.first; });
87 for (
int i_adc = 0; i_adc <
n_ad_cs_; i_adc++) {
89 ldmx_log(trace) <<
" iADC = " << i_adc <<
" at startBX = " << start_bx;
93 bool start_tot =
false;
94 bool over_toa =
false;
95 double tover_toa = -1;
96 double tover_tot = -1;
97 for (
auto hit : pulse.
hits()) {
100 if (hit_bx != i_adc) {
104 double vpeak = pulse(hit.second);
106 if (vpeak > tot_threshold) {
109 if (!start_tot || tover_tot < hit.second) {
110 tover_tot = hit.second;
115 if (vpeak > toa_threshold) {
116 if (!over_toa || hit.second < tover_toa) tover_toa = hit.second;
123 if (!over_toa && pulse(start_bx +
clock_cycle_) > toa_threshold) {
124 if (pulse(start_bx) < toa_threshold) {
138 double charge_deposited =
150 double tot = charge_deposited / drain_rate;
151 ldmx_log(trace) <<
" we are in TOT read-out mode, TOT = " << tot;
156 int tdc_counts = int(tot * 4096 / tot_max) +
pedestal;
163 toa = digiToAdd.back().toa();
168 toa = int((timecross - start_bx) *
ns_);
170 if (toa == 0) toa = 1;
171 if (toa > 1023) toa = 1023;
174 auto adc_at_tminus1 =
175 (i_adc > 0) ? digiToAdd.at(i_adc - 1).adcT() :
pedestal;
176 ldmx_log(trace) <<
" Adding TOT hit with toa = " << toa
177 <<
", tdc_counts = " << tdc_counts
178 <<
" adcT at prev iADC = " << adc_at_tminus1;
179 auto i_tot_sample = digiToAdd.size();
181 digiToAdd.emplace_back(
false,
true, adc_at_tminus1, tdc_counts, toa);
186 <<
" Adding further hits_ with ADC [t-1] = 0x3FF, toa = "
187 "0x3FF, until digiToAdd.size() = "
188 << digiToAdd.size() <<
" < n_ad_cs_(" <<
n_ad_cs_ <<
")";
189 while (digiToAdd.size() <
n_ad_cs_) {
191 digiToAdd.emplace_back(
true,
false, 0x3FF, 0x3FF, 0);
194 return (i_tot_sample <=
i_soi_ + 1);
201 int adc = bxvolts /
gain;
202 ldmx_log(trace) <<
" we are in ADC read-out mode, adc = " << adc;
203 if (adc < 0) adc = 0;
204 if (adc > 1023) adc = 1023;
208 if (pulse(start_bx) < toa_threshold && over_toa) {
211 toa = int((timecross - start_bx) *
ns_);
213 if (toa == 0) toa = 1;
214 if (toa > 1023) toa = 1023;
221 (i_adc > 0) ? digiToAdd.at(i_adc - 1).adcT() :
pedestal;
223 digiToAdd.emplace_back(
false,
false, adc_t_minus1, adc, toa);
227 if (save_pulse_truth_info_)
232 ldmx_log(trace) <<
" we are adding the hit IFF iSOI= " <<
i_soi_
233 <<
"'s adc_t = " << digiToAdd.at(
i_soi_).adcT()
234 <<
" >= thresh (" << readout_threshold <<
")";
235 return digiToAdd.at(
i_soi_).adcT() >= readout_threshold;
239 const int& channel,
const double& soi_amplitude)
const {
244 std::vector<ldmx::HgcrocDigiCollection::Sample> noise_digi;
245 for (
int i_adc{0}; i_adc <
n_ad_cs_; i_adc++) {
248 int adc_tm1{
static_cast<int>(
pedestal)};
250 adc_tm1 = noise_digi.at(i_adc - 1).adcT();
257 if (i_adc ==
i_soi_) adc_t += soi_amplitude /
gain;
261 noise_digi.emplace_back(
false,
false, adc_tm1, adc_t, 0);
Class encapsulating parameters for configuring a processor.
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
const std::vector< std::pair< double, double > > & hits() const
Get list of individual pulses that are entering the chip.
void addOrMerge(const std::pair< double, double > &hit, double hit_merge_ns)
Put another hit into this composite pulse.
double findCrossing(double low, double high, double level, double prec=0.01)
Find the time at which we cross the input level.
std::unique_ptr< TRandom3 > noise_injector_
Generates Gaussian noise on top of real hits_.
double readoutThreshold(const int &id) const
Readout Threshold (ADC Counts)
double clock_cycle_
Time interval for chip clock [ns].
void seedGenerator(uint64_t seed)
Seed the emulator for random number generation.
int n_ad_cs_
Depth of ADC buffer.
double noise(const int &channelID) const
Get random noise amplitdue for input channel [mV].
double pedestal(const int &id) const
Pedestal [ADC Counts] for input channel.
double timing_jitter_
Jitter of timing mechanism in the chip [ns].
double getCondition(int id, const std::string &name) const
Get condition for input chip ID, condition name, and default value.
double time_up_slope_
Time of Up Slope relative to Pulse Shape Fit [ns].
double hit_merge_ns_
Hit merging time [ns].
double rate_dn_slope_
Rate of Down Slope in Pulse Shape [1/ns].
int i_soi_
Index for the Sample Of Interest in the list of digi samples.
double time_dn_slope_
Time of Down Slope relative to Pulse Shape Fit [ns].
TF1 pulse_func_
Functional shape of signal pulse in time.
bool digitize(const int &channelID, std::vector< std::pair< double, double > > &arriving_pulses, std::vector< ldmx::HgcrocDigiCollection::Sample > &digiToAdd) const
Digitize the signals from the simulated hits_.
double gain(const int &channelID) const
Gain for input channel.
bool noise_
Put noise in channels, only configure to false if testing.
double time_peak_
Time of Peak relative to pulse shape fit [ns].
std::vector< ldmx::HgcrocDigiCollection::Sample > noiseDigi(const int &channel, const double &soi_amplitude=0) const
Generate a digi of pure noise.
HgcrocEmulator(const framework::config::Parameters &ps)
Constructor.
double ns_
Conversion from time [ns] to counts.
double rate_up_slope_
Rate of Up Slope in Pulse Shape [1/ns].