12 #ifndef WaveformDigitizerSim_h 13 #define WaveformDigitizerSim_h 25 #include "cetlib_except/exception.h" 36 #include "nurandom/RandomUtils/NuRandomService.h" 55 #include "CLHEP/Random/RandGauss.h" 75 typedef std::vector< std::pair< size_t, size_t > >
Ranges_t;
89 for(
size_t i = 0; i <
ranges.size(); ++i){
90 pair<size_t, size_t>&
r =
ranges[i];
92 if(from >= r.first && to <= r.second)
return;
94 if(from >= r.first && from <= r.second){
99 if(to >= r.first && to <= r.second){
105 ranges.emplace_back(from, to);
137 Comment(
"1PE pulse length in us") };
139 Comment(
"Time when the pulse reaches its maximum in us") };
141 Comment(
"Maximum amplitude of the pulse in mV") };
143 Comment(
"Constant in the exponential function of the leading edge in us") };
145 Comment(
"Constant in the exponential function of the tail in us") };
149 Comment(
"Minimum ticks around pulses to simulate")};
151 Comment(
"Total size of the triggered readout window in ticks")};
153 Comment(
"Length of the ReadoutWindow which comes before the trigger in ticks")};
155 Comment(
"Minimum threshold to trigger readout in the CFD (PE)")};
157 Comment(
"Sample time difference in the CFD trigger in ticks")};
161 Comment(
"Baseline pedestal in ADC counts")};
163 Comment(
"Pedestal RMS in ADC counts")};
165 Comment(
"Maximum number of bits in readout if specified.") };
169 Comment(
"Override earliest allowed waveform time, default -1 drift window") };
171 Comment(
"Override latest allowed waveform time, default end of TPC readout") };
173 Comment(
"Write out the whole waveform, slow with *large* output sizes. Default false."),
237 void CreateSinglePEWaveform();
238 double Pulse1PE(
double time_in_us)
const;
239 void SetDefaultBeginEndTimes();
240 void CheckFHiCLParameters()
const;
264 template<
typename T> Ranges_t CFDTrigger(vector<T>
const& wf,
const FocusList& fls)
const;
269 double Tick2us(
size_t tick)
const {
return fTimeBegin +
static_cast<double>(
tick)/fSampleFreqMHz; };
270 double Tick2ns(
size_t tick)
const {
return 1000.*Tick2us(tick); };
271 size_t us2Tick(
double time_in_us)
const {
return static_cast<size_t>(std::round( (time_in_us-fTimeBegin)*fSampleFreqMHz) ); }
272 size_t ns2Tick(
double time_in_ns)
const {
return us2Tick(time_in_ns/1000.); };
320 "SeedWaveformDigi") )
325 produces< vector< raw::OpDetWaveform > >();
328 consumes< vector< sim::OpDetDivRec > >(
tag);
336 logger <<
"Using a sampling frequency of " <<
fSampleFreqMHz <<
" MHz" <<
"\n";
342 logger <<
"Requested pulse length of, " <<
fPulseLength <<
" us " 344 logger <<
"Requested PE threshold, " << std::fixed
346 <<
", converted to ADC threshold " 352 if (
config().DynamicBitRange(br) ) {
354 logger <<
"Limiting output to " << br <<
" bits" <<
"\n";
361 tsource =
"override";
366 logger <<
"Using " << tsource <<
" time limits on PD digitizer: " <<
fTimeBegin <<
" us to " <<
fTimeEnd <<
" us";
382 if (val > maxADC) maxADC =
val;
409 fTimeEnd = detProp.ReadOutWindowSize() / clockData.TPCClock().Frequency() + 5;
423 <<
"No input tags were given to WaveformDigitizerSim.\n";
429 <<
"Line noise RMS should be non-negative!\n";
435 <<
"TimeBegin should be less than TimeEnd!\n";
451 auto wave_forms_p = std::make_unique< vector< raw::OpDetWaveform > >();
458 std::map< int, vector<const sim::OpDetDivRec *> > DivRecsByChannel;
460 auto dr_handle =
event.getHandle< vector< sim::OpDetDivRec > >(
tag);
462 mf::LogWarning(
"WaveformDigitizerSim") <<
"Could not load OpDetDivRecs " <<
tag <<
". Skipping.";
465 for (
auto const& dr : *dr_handle) {
466 DivRecsByChannel[dr.OpDetNum()].push_back( &dr );
471 for (
auto const& [opDet, vDivRecs]: DivRecsByChannel)
487 wave_forms_p->emplace_back(
Tick2us(0), opDet,
Digitize(pdWaveform.begin(), pdWaveform.end()));
496 auto shortWF =
Digitize(pdWaveform.begin()+
t.first, pdWaveform.begin()+
t.second+1);
497 wave_forms_p->emplace_back(
Tick2us(
t.first), opDet, shortWF);
516 double photonTime_ns = odtc.time;
517 size_t timeBin =
ns2Tick(photonTime_ns);
520 if ( timeBin < 0 || timeBin >= pdWaveform.
size() ) {
521 mf::LogWarning(
"WaveformDigitizerSim") <<
"Skipping a photon at " << photonTime_ns/1000. <<
" us, outside digitization window of " <<
fTimeBegin <<
" to " <<
fTimeEnd;
527 for (
auto const& sdp : odtc.phots)
534 fls.
AddRange(timeBin, timeBin+stop-1);
548 for(
auto k =
p.first;
k <=
p.second; ++
k){
557 for(
auto it = itBegin; it != itEnd; ++it) {
563 return vector< uint16_t >(itBegin, itEnd);
573 for (
auto range: fls.
ranges) {
597 else if (fire &&
tick >= wend) {
600 readouts.emplace_back(wstart, wend);
608 readouts.emplace_back(wstart, range.second-1);
base_engine_t & createEngine(seed_t seed)
Store parameters for running LArG4.
void AddRange(int from, int to)
FocusList(size_t nSamples, size_t padding)
ChannelGroupService::Name Name
std::vector< std::pair< size_t, size_t > > Ranges_t
Q_EXPORT QTSManip setprecision(int p)
std::vector< std::pair< int, int > > ranges
Simulation objects for optical detectors.
#define DEFINE_ART_MODULE(klass)
Time_Chans_t const & GetTimeChans() const
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
static int max(int a, int b)
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Tools and modules for checking out the basics of the Monte Carlo.
Event finding and building.
void AddRange(size_t from, size_t to)