11 #ifndef OpDetDigitizerDUNE_h 12 #define OpDetDigitizerDUNE_h 23 #include "cetlib_except/exception.h" 26 #include "art_root_io/TFileService.h" 27 #include "art_root_io/TFileDirectory.h" 32 #include "nurandom/RandomUtils/NuRandomService.h" 51 #include "CLHEP/Random/RandGauss.h" 52 #include "CLHEP/Random/RandExponential.h" 53 #include "CLHEP/Random/RandFlat.h" 80 if(from < 0) from = 0;
83 for(
unsigned int i = 0; i <
ranges.size(); ++i){
84 std::pair<int, int>&
r =
ranges[i];
86 if(from >= r.first && to <= r.second)
return;
88 if(from >= r.first && from <= r.second){
93 if(to >= r.first && to <= r.second){
99 ranges.emplace_back(from, to);
166 void AddPulse(
size_t timeBin,
int scale,
167 std::vector< double >& waveform,
171 double Pulse1PE(
double time)
const;
183 void CheckFHiCLParameters()
const;
186 void CreateSinglePEWaveform();
192 std::vector<FocusList>& fls,
197 void AddLineNoise(
std::vector< std::vector< double > >&,
198 const std::vector<FocusList>& fls)
const;
200 void AddDarkNoise(
std::vector< std::vector< double > >&,
201 std::vector<FocusList>& fls)
const;
203 unsigned short CrossTalk()
const;
207 std::vector< short > VectorOfDoublesToVectorOfShorts(std::vector< double >
const&)
const;
211 std::map< size_t, std::vector< short > > SplitWaveform(std::vector< short >
const&,
218 double TickToTime(
size_t tick)
const;
219 size_t TimeToTick(
double time)
const;
222 bool Detected(
int opDet,
int &readoutChannel,
bool Reflected);
241 ,
vInputModules(pset.get< std::vector<std::string> >(
"InputModules"))
252 fCrossTalk = pset.get<
double >(
"CrossTalk" );
253 fPedestal = pset.get<
short >(
"Pedestal" );
259 fPadding = pset.get<
int >(
"Padding" );
262 fPeakTime = pset.get<
double >(
"PeakTime" );
264 fFrontTime = pset.get<
double >(
"FrontTime" );
265 fBackTime = pset.get<
double >(
"BackTime" );
267 fUseSDPs = pset.get<
bool >(
"UseSDPs", true );
274 double tempQE = pset.get<
double >(
"QEOverride", 0 );
275 double tempRefQE = pset.get<
double >(
"QERefOverride", 0 );
281 mf::LogInfo(
"OpDetDigitizerDUNE") <<
"Overriding QE. All the functions of OpDetResponseService being ignored.";
284 auto const *LarProp = lar::providerFrom<detinfo::LArPropertiesService>();
285 fQEOverride = tempQE / LarProp->ScintPreScale();
287 if (fQEOverride > 1.0001 ) {
288 mf::LogError(
"OpDetDigitizerDUNE") <<
"Quantum efficiency set as OpDetDigitizerDUNE.QEOverride, " << tempQE
289 <<
" is too large. It is larger than the prescaling applied during simulation, " 290 << LarProp->ScintPreScale()
291 <<
" (fQEOverride = " 293 <<
"). Final QE must be equal to or smaller than the QE applied at simulation time.";
298 mf::LogInfo(
"OpDetDigitizerDUNE") <<
"Overriding QE. All the functions of OpDetResponseService being ignored.";
301 auto const *LarProp = lar::providerFrom<detinfo::LArPropertiesService>();
304 if (fRefQEOverride > 1.0001 ) {
305 mf::LogError(
"OpDetDigitizerDUNE") <<
"Quantum efficiency set as OpDetDigitizerDUNE.QERefOverride, " << tempRefQE
306 <<
" is too large. It is larger than the prescaling applied during simulation, " 307 << LarProp->ScintPreScale()
308 <<
" (fRefQEOverride = " 310 <<
"). Final QE must be equal to or smaller than the QE applied at simulation time.";
315 fThreshAlg = std::make_unique< pmtana::AlgoSSPLeadingEdge >
318 if(fDigiTree_SSP_LED){
320 arvore2 = tfs->make<TTree>(
"PhotonData",
"Photon_analysis");
326 produces< std::vector< raw::OpDetWaveform > >();
327 produces<std::vector<sim::OpDetDivRec> > ();
332 fSampleFreq = clockData.OpticalClock().Frequency();
334 if (fDefaultSimWindow)
343 fTimeEnd = detProp.ReadOutWindowSize() / clockData.TPCClock().Frequency();
348 fTimeEnd = pset.get<
double >(
"TimeEnd" );
356 fRandGauss = std::make_unique< CLHEP::RandGauss >(engine);
358 fRandFlat = std::make_unique< CLHEP::RandFlat >(engine);
380 auto wave_forms_p = std::make_unique< std::vector< raw::OpDetWaveform > >();
381 auto bt_DivRec_p = std::make_unique< std::vector< sim::OpDetDivRec > >();
393 auto const btr_handles = evt.
getMany<std::vector<sim::OpDetBacktrackerRecord>>();
395 if (btr_handles.size() == 0)
398 for (
auto btr_handle: btr_handles) {
400 if (!btr_handle.isValid())
continue;
401 if (!
fInputModules.count(btr_handle.provenance()->moduleLabel()))
continue;
403 bool Reflected = (btr_handle.provenance()->productInstanceName() ==
"Reflected");
406 std::vector<art::Ptr<sim::OpDetBacktrackerRecord>> btr_vec;
411 for (
auto const& btr : btr_vec)
413 int opDet = btr->OpDetNum();
425 std::vector< std::vector< double > > pdWaveforms(nChannelsPerOpDet,
426 std::vector< double >(nSamples, static_cast< double >(
fPedestal)));
448 for (
unsigned int hardwareChannel = 0;
449 hardwareChannel < nChannelsPerOpDet; ++hardwareChannel)
451 for(
const std::pair<int, int>&
p: fls[hardwareChannel].
ranges){
454 const std::vector<double>
sub(pdWaveforms[hardwareChannel].
begin()+
p.first,
455 pdWaveforms[hardwareChannel].begin()+
p.second+1);
459 std::map< size_t, std::vector < short > > mapTickWaveform =
462 std::map< size_t, std::vector< short > >{ std::make_pair(0,
465 unsigned int opChannel = geometry->
OpChannel(opDet, hardwareChannel);
467 for (
auto const& pairTickWaveform : mapTickWaveform)
470 static_cast< double >(
TickToTime(pairTickWaveform.first+
p.first));
473 pairTickWaveform.second.size());
475 for (
short const&
value : pairTickWaveform.second){
476 adcVec.emplace_back(value);
480 wave_forms_p->push_back(
std::move(adcVec));
486 bt_DivRec_p->push_back(
std::move(DivRec));
506 int scale, std::vector< double >& waveform,
513 pulseLength = (waveform.size() - timeBin);
515 fl.
AddRange(timeBin, timeBin+pulseLength-1);
552 std::vector<FocusList>& fls,
557 int const opDet = btr_p->
OpDetNum();
576 for (
size_t i = 0; i<time_sdps_vector.size(); ++i)
578 auto time_sdps = time_sdps_vector[i];
582 double photonTime = time_sdps.first/1000.0;
585 for (
auto const& sdp : time_sdps.second)
587 int tid = sdp.trackID;
588 for(
int j=0; j<sdp.numPhotons;++j)
593 if (
Detected(opDet, readoutChannel, Reflected) )
595 unsigned int hardwareChannel =
600 AddPulse(timeBin,
CrossTalk(), pdWaveforms.at(hardwareChannel), fls[hardwareChannel]);
602 unsigned int opChannel = geometry.
OpChannel(opDet, hardwareChannel);
605 DivRec.
AddPhoton(opChannel, tid, tmp_time);
640 const std::vector<FocusList>& fls)
const 643 for(
auto& waveform : waveforms){
644 for(
unsigned int j = 0; j < fls[i].ranges.size(); ++j){
645 const std::pair<int, int>&
p = fls[i].ranges[j];
646 for(
int k = p.first;
k <= p.second; ++
k){
658 std::vector<FocusList>& fls)
const 661 for (
auto& waveform : waveforms)
671 darkNoiseTime +=
static_cast< double > 690 (std::vector< double >
const& vectorOfDoubles)
const 693 return std::vector<short>(vectorOfDoubles.begin(), vectorOfDoubles.end());
712 std::map< size_t, std::vector< short > > mapTickWaveform;
717 fThreshAlg->Reconstruct(waveform,ped_mean,ped_sigma);
719 std::vector< pmtana::pulse_param > pulses;
720 for (
size_t pulseCounter = 0; pulseCounter <
fThreshAlg->GetNPulse();
722 pulses.emplace_back(
fThreshAlg->GetPulse(pulseCounter));
727 if (pulse.t_end <= pulse.t_start)
730 <<
"Pulse ends before or at the same time it starts!\n";
733 waveform.begin() +
static_cast< size_t >(pulse.t_start);
735 waveform.begin() +
static_cast< size_t >(pulse.t_end );
736 mapTickWaveform.emplace(static_cast< size_t >(pulse.t_start),
737 std::vector< short >(window_start, window_end));
743 return mapTickWaveform;
753 double maxDrift = 0.0;
756 if (maxDrift < tpc.DriftDistance()) maxDrift = tpc.DriftDistance();
795 <<
"Line noise RMS should be non-negative!\n";
800 <<
"Dark noise rate should be non-negative!\n";
806 <<
"Pretrigger window has to be shorter than readout window!\n";
812 <<
"TimeBegin should be less than TimeEnd!\n";
820 cet::exception(
"OpDetDigitizerDUNE") <<
"Cannot handle reflected light if QERefOverride isn't set";
822 if ( (!Reflected &&
fQEOverride > 0) || Reflected ) {
830 readoutChannel = geom->
OpChannel(OpDet, hardwareChannel);
834 if ( CLHEP::RandFlat::shoot(1.0) >
fQEOverride )
return false;
base_engine_t & createEngine(seed_t seed)
Store parameters for running LArG4.
bool Detected(int opDet, int &readoutChannel, bool Reflected)
void AddLineNoise(std::vector< std::vector< double > > &, const std::vector< FocusList > &fls) const
std::vector< double > PedestalSigma_t
FocusList(int nSamples, int padding)
void AddRange(int from, int to)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Geometry information for a single TPC.
unsigned int NOpHardwareChannels(int opDet) const
std::map< size_t, std::vector< short > > SplitWaveform(std::vector< short > const &, const FocusList &)
void AddPulse(size_t timeBin, int scale, std::vector< double > &waveform, FocusList &fl) const
size_t TimeToTick(double time) const
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
double GetDriftWindow(detinfo::DetectorPropertiesData const &detProp) const
void CreateSinglePEWaveform()
std::vector< std::pair< int, int > > ranges
OpDetDigitizerDUNE(fhicl::ParameterSet const &)
void produce(art::Event &)
std::vector< double > fSinglePEWaveform
Simulation objects for optical detectors.
int OpDetNum() const
Returns the readout Optical Detector this object describes.
std::unique_ptr< CLHEP::RandExponential > fRandExponential
#define DEFINE_ART_MODULE(klass)
double Pulse1PE(double time) const
unsigned int HardwareChannelFromOpChannel(int opChannel) const
Convert unique channel to hardware channel.
std::vector< Handle< PROD > > getMany(SelectorBase const &selector=MatchAllSelector{}) const
std::vector< std::string > vInputModules
std::unique_ptr< pmtana::AlgoSSPLeadingEdge > fThreshAlg
void AddDarkNoise(std::vector< std::vector< double > > &, std::vector< FocusList > &fls) const
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
std::vector< int > op_photon
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
void CreatePDWaveform(art::Ptr< sim::OpDetBacktrackerRecord > const &btr_p, geo::Geometry const &geometry, std::vector< std::vector< double > > &pdWaveforms, std::vector< FocusList > &fls, sim::OpDetDivRec &DivRec, bool Reflected)
std::unique_ptr< CLHEP::RandGauss > fRandGauss
std::unique_ptr< CLHEP::RandFlat > fRandFlat
double DriftVelocity(double efield=0., double temperature=0.) const
cm/us
The geometry of one entire detector, as served by art.
virtual bool detectedLite(int OpChannel, int &newOpChannel) const
unsigned int OpChannel(int detNum, int hardwareChannel) const
Convert detector number and hardware channel to unique channel.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
unsigned int GetRandomNumberSeed()
double TickToTime(size_t tick) const
Index NOpHardwareChannels(Index opDet)
std::vector< double > t_photon
std::vector< short > VectorOfDoublesToVectorOfShorts(std::vector< double > const &) const
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Tools and modules for checking out the basics of the Monte Carlo.
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
void CheckFHiCLParameters() const
std::vector< double > PedestalMean_t
unsigned short CrossTalk() const
timePDclockSDPs_t const & timePDclockSDPsMap() const
Returns all the deposited energy information as stored.
cet::coded_exception< error, detail::translate > exception
void AddPhoton(int opchan, int tid, OpDet_Time_Chans::stored_time_t pdTime)
std::set< std::string > fInputModules
std::string sub(const std::string &a, const std::string &b)