13 #ifndef OpDetDigitizerProtoDUNE_h 14 #define OpDetDigitizerProtoDUNE_h 25 #include "cetlib_except/exception.h" 27 #include "art_root_io/TFileService.h" 28 #include "art_root_io/TFileDirectory.h" 34 #include "nurandom/RandomUtils/NuRandomService.h" 53 #include "CLHEP/Random/RandGauss.h" 54 #include "CLHEP/Random/RandExponential.h" 55 #include "CLHEP/Random/RandFlat.h" 82 if(from < 0) from = 0;
85 for(
unsigned int i = 0; i <
ranges.size(); ++i){
86 std::pair<int, int>&
r =
ranges[i];
88 if(from >= r.first && to <= r.second)
return;
90 if(from >= r.first && from <= r.second){
95 if(to >= r.first && to <= r.second){
101 ranges.emplace_back(from, to);
104 std::vector<std::pair<int, int>>
ranges;
170 void AddPulse(
size_t timeBin,
int scale,
171 std::vector< double >& waveform,
175 double Pulse1PE(
double time)
const;
187 void CheckFHiCLParameters()
const;
190 void CreateSinglePEWaveform();
196 std::vector<FocusList>& fls,
201 void AddLineNoise(
std::vector< std::vector< double > >&,
202 const std::vector<FocusList>& fls)
const;
204 void AddDarkNoise(
std::vector< std::vector< double > >&,
205 std::vector<FocusList>& fls)
const;
207 unsigned short CrossTalk()
const;
211 std::vector< short > VectorOfDoublesToVectorOfShorts(std::vector< double >
const&)
const;
215 std::map< size_t, std::vector< short > > SplitWaveform(std::vector< short >
const&,
222 double TickToTime(
size_t tick)
const;
223 size_t TimeToTick(
double time)
const;
226 bool Detected(
int opDet,
int &readoutChannel,
bool Reflected);
245 ,
vInputModules(pset.get< std::vector<std::string> >(
"InputModules"))
256 fCrossTalk = pset.get<
double >(
"CrossTalk" );
257 fPedestal = pset.get<
short >(
"Pedestal" );
263 fPadding = pset.get<
int >(
"Padding" );
266 fPeakTime = pset.get<
double >(
"PeakTime" );
268 fFrontTime = pset.get<
double >(
"FrontTime" );
269 fBackTime = pset.get<
double >(
"BackTime" );
271 fUseSDPs = pset.get<
bool >(
"UseSDPs", true );
278 double tempQE = pset.get<
double >(
"QEOverride", 0 );
279 double tempQEArapucaBeam = pset.get<
double >(
"QEArapucaBeamOverride", 0 );
280 double tempQEArapucaNonBeam = pset.get<
double >(
"QEArapucaNonBeamOverride", 0 );
287 mf::LogInfo(
"OpDetDigitizerProtoDUNE") <<
"Overriding QE. All the functions of OpDetResponseService being ignored.";
290 auto const *LarProp = lar::providerFrom<detinfo::LArPropertiesService>();
291 fQEOverride = tempQE / LarProp->ScintPreScale();
293 if (fQEOverride > 1.0001) {
294 mf::LogError(
"OpDetDigitizerProtoDUNE") <<
"Quantum efficiency set as OpDetDigitizerProtoDUNE.QEOverride, " << tempQE
295 <<
" is too large. It is larger than the prescaling applied during simulation, " 296 << LarProp->ScintPreScale()
297 <<
" (fQEOverride = " << fQEOverride
298 <<
"). Final QE must be equal to or smaller than the QE applied at simulation time.";
303 if (tempQEArapucaBeam > 0) {
304 mf::LogInfo(
"OpDetDigitizerProtoDUNE") <<
"Overriding QE. All the functions of OpDetResponseService being ignored.";
307 auto const *LarProp = lar::providerFrom<detinfo::LArPropertiesService>();
310 if (fQEArapucaBeamOverride > 1.0001) {
311 mf::LogError(
"OpDetDigitizerProtoDUNE") <<
"Quantum efficiency set as OpDetDigitizerProtoDUNE.QEOverride, " << tempQEArapucaBeam
312 <<
" is too large. It is larger than the prescaling applied during simulation, " 313 << LarProp->ScintPreScale()
314 <<
" fQEArapucaBeamOverride = " << fQEArapucaBeamOverride
315 <<
"). Final QE must be equal to or smaller than the QE applied at simulation time.";
319 if (tempQEArapucaNonBeam > 0) {
320 mf::LogInfo(
"OpDetDigitizerProtoDUNE") <<
"Overriding QE. All the functions of OpDetResponseService being ignored.";
323 auto const *LarProp = lar::providerFrom<detinfo::LArPropertiesService>();
326 if (fQEArapucaNonBeamOverride > 1.0001) {
327 mf::LogError(
"OpDetDigitizerProtoDUNE") <<
"Quantum efficiency set as OpDetDigitizerProtoDUNE.QEOverride, " << tempQEArapucaNonBeam
328 <<
" is too large. It is larger than the prescaling applied during simulation, " 329 << LarProp->ScintPreScale()
330 <<
" fQEArapucaNonBeamOverride = " << fQEArapucaNonBeamOverride
331 <<
"). Final QE must be equal to or smaller than the QE applied at simulation time.";
336 fThreshAlg = std::make_unique< pmtana::AlgoSSPLeadingEdge >
339 if(fDigiTree_SSP_LED){
341 arvore2 = tfs->make<TTree>(
"PhotonData",
"Photon_analysis");
347 produces< std::vector< raw::OpDetWaveform > >();
348 produces<std::vector<sim::OpDetDivRec> > ();
353 fSampleFreq = clockData.OpticalClock().Frequency();
355 if (fDefaultSimWindow)
364 fTimeEnd = detProp.ReadOutWindowSize() / clockData.TPCClock().Frequency();
369 fTimeEnd = pset.get<
double >(
"TimeEnd" );
377 fRandGauss = std::make_unique< CLHEP::RandGauss >(engine);
379 fRandFlat = std::make_unique< CLHEP::RandFlat >(engine);
401 auto wave_forms_p = std::make_unique< std::vector< raw::OpDetWaveform > >();
402 auto bt_DivRec_p = std::make_unique< std::vector< sim::OpDetDivRec > >();
414 auto const btr_handles = evt.
getMany<std::vector<sim::OpDetBacktrackerRecord>>();
416 if (btr_handles.size() == 0)
419 for (
auto btr_handle: btr_handles) {
421 if (!btr_handle.isValid())
continue;
422 if (!
fInputModules.count(btr_handle.provenance()->moduleLabel()))
continue;
424 bool Reflected = (btr_handle.provenance()->productInstanceName() ==
"Reflected");
427 std::vector<art::Ptr<sim::OpDetBacktrackerRecord>> btr_vec;
432 for (
auto const& btr : btr_vec)
434 int opDet = btr->OpDetNum();
446 std::vector< std::vector< double > > pdWaveforms(nChannelsPerOpDet,
447 std::vector< double >(nSamples, static_cast< double >(
fPedestal)));
469 for (
unsigned int hardwareChannel = 0;
470 hardwareChannel < nChannelsPerOpDet; ++hardwareChannel)
472 for(
const std::pair<int, int>&
p: fls[hardwareChannel].
ranges){
475 const std::vector<double>
sub(pdWaveforms[hardwareChannel].
begin()+
p.first,
476 pdWaveforms[hardwareChannel].begin()+
p.second+1);
480 std::map< size_t, std::vector < short > > mapTickWaveform =
483 std::map< size_t, std::vector< short > >{ std::make_pair(0,
486 unsigned int opChannel = geometry->
OpChannel(opDet, hardwareChannel);
488 for (
auto const& pairTickWaveform : mapTickWaveform)
491 static_cast< double >(
TickToTime(pairTickWaveform.first+
p.first));
494 pairTickWaveform.second.size());
496 for (
short const&
value : pairTickWaveform.second){
497 adcVec.emplace_back(value);
501 wave_forms_p->push_back(
std::move(adcVec));
507 bt_DivRec_p->push_back(
std::move(DivRec));
527 int scale, std::vector< double >& waveform,
534 pulseLength = (waveform.size() - timeBin);
536 fl.AddRange(timeBin, timeBin+pulseLength-1);
573 std::vector<FocusList>& fls,
578 int const opDet = btr_p->
OpDetNum();
597 for (
size_t i = 0; i<time_sdps_vector.size(); ++i)
599 auto time_sdps = time_sdps_vector[i];
603 double photonTime = time_sdps.first/1000.0;
606 for (
auto const& sdp : time_sdps.second)
608 int tid = sdp.trackID;
609 for(
int j=0; j<sdp.numPhotons;++j)
614 if (
Detected(opDet, readoutChannel, Reflected) )
616 unsigned int hardwareChannel =
621 AddPulse(timeBin,
CrossTalk(), pdWaveforms.at(hardwareChannel), fls[hardwareChannel]);
623 unsigned int opChannel = geometry.
OpChannel(opDet, hardwareChannel);
626 DivRec.
AddPhoton(opChannel, tid, tmp_time);
661 const std::vector<FocusList>& fls)
const 664 for(
auto& waveform : waveforms){
665 for(
unsigned int j = 0; j < fls[i].ranges.size(); ++j){
666 const std::pair<int, int>&
p = fls[i].ranges[j];
667 for(
int k = p.first;
k <= p.second; ++
k){
679 std::vector<FocusList>& fls)
const 682 for (
auto& waveform : waveforms)
692 darkNoiseTime +=
static_cast< double > 711 (std::vector< double >
const& vectorOfDoubles)
const 714 return std::vector<short>(vectorOfDoubles.begin(), vectorOfDoubles.end());
733 std::map< size_t, std::vector< short > > mapTickWaveform;
738 fThreshAlg->Reconstruct(waveform,ped_mean,ped_sigma);
740 std::vector< pmtana::pulse_param > pulses;
741 for (
size_t pulseCounter = 0; pulseCounter <
fThreshAlg->GetNPulse();
743 pulses.emplace_back(
fThreshAlg->GetPulse(pulseCounter));
748 if (pulse.t_end <= pulse.t_start)
751 <<
"Pulse ends before or at the same time it starts!\n";
754 waveform.begin() +
static_cast< size_t >(pulse.t_start);
756 waveform.begin() +
static_cast< size_t >(pulse.t_end );
757 mapTickWaveform.emplace(static_cast< size_t >(pulse.t_start),
758 std::vector< short >(window_start, window_end));
764 return mapTickWaveform;
774 double maxDrift = 0.0;
777 if (maxDrift < tpc.DriftDistance()) maxDrift = tpc.DriftDistance();
816 <<
"Line noise RMS should be non-negative!\n";
821 <<
"Dark noise rate should be non-negative!\n";
827 <<
"Pretrigger window has to be shorter than readout window!\n";
833 <<
"TimeBegin should be less than TimeEnd!\n";
848 readoutChannel = geom->
OpChannel(OpDet, hardwareChannel);
851 if (OpDet>28 && OpDet<45) {
855 if (OpDet>44 && OpDet<61) {
859 if ( CLHEP::RandFlat::shoot(1.0) >
fQEOverride )
return false;
void AddDarkNoise(std::vector< std::vector< double > > &, std::vector< FocusList > &fls) const
base_engine_t & createEngine(seed_t seed)
Store parameters for running LArG4.
std::vector< std::string > vInputModules
void CreateSinglePEWaveform()
std::vector< double > PedestalSigma_t
FocusList(int nSamples, int padding)
void AddRange(int from, int to)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
bool Detected(int opDet, int &readoutChannel, bool Reflected)
std::unique_ptr< CLHEP::RandGauss > fRandGauss
std::unique_ptr< CLHEP::RandFlat > fRandFlat
double TickToTime(size_t tick) const
Geometry information for a single TPC.
std::vector< int > op_photon
double GetDriftWindow(detinfo::DetectorPropertiesData const &detProp) const
unsigned int NOpHardwareChannels(int opDet) const
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::vector< double > fSinglePEWaveform
OpDetDigitizerProtoDUNE(fhicl::ParameterSet const &)
void produce(art::Event &)
std::vector< std::pair< int, int > > ranges
Simulation objects for optical detectors.
int OpDetNum() const
Returns the readout Optical Detector this object describes.
#define DEFINE_ART_MODULE(klass)
std::vector< short > VectorOfDoublesToVectorOfShorts(std::vector< double > const &) const
unsigned int HardwareChannelFromOpChannel(int opChannel) const
Convert unique channel to hardware channel.
std::vector< Handle< PROD > > getMany(SelectorBase const &selector=MatchAllSelector{}) const
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
std::vector< double > t_photon
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
double fQEArapucaNonBeamOverride
double DriftVelocity(double efield=0., double temperature=0.) const
cm/us
The geometry of one entire detector, as served by art.
std::map< size_t, std::vector< short > > SplitWaveform(std::vector< short > const &, const FocusList &)
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()
void AddLineNoise(std::vector< std::vector< double > > &, const std::vector< FocusList > &fls) const
size_t TimeToTick(double time) const
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)
Index NOpHardwareChannels(Index opDet)
std::unique_ptr< pmtana::AlgoSSPLeadingEdge > fThreshAlg
std::set< std::string > fInputModules
std::unique_ptr< CLHEP::RandExponential > fRandExponential
void AddPulse(size_t timeBin, int scale, std::vector< double > &waveform, FocusList &fl) const
void CheckFHiCLParameters() 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)
unsigned short CrossTalk() const
std::vector< double > PedestalMean_t
timePDclockSDPs_t const & timePDclockSDPsMap() const
Returns all the deposited energy information as stored.
void AddPhoton(int opchan, int tid, OpDet_Time_Chans::stored_time_t pdTime)
double Pulse1PE(double time) const
double fQEArapucaBeamOverride
std::string sub(const std::string &a, const std::string &b)