21 #include "nurandom/RandomUtils/NuRandomService.h"
24 #include "art/Framework/Core/EDProducer.h"
25 #include "art/Framework/Core/ModuleMacros.h"
26 #include "art/Framework/Principal/Event.h"
27 #include "art/Framework/Principal/Handle.h"
28 #include "art/Framework/Services/Registry/ServiceHandle.h"
29 #include "art/Framework/Services/Optional/RandomNumberGenerator.h"
30 #include "art/Utilities/make_tool.h"
31 #include "canvas/Utilities/InputTag.h"
32 #include "messagefacility/MessageLogger/MessageLogger.h"
33 #include "fhiclcpp/types/DelegatedParameter.h"
34 #include "fhiclcpp/types/TableFragment.h"
35 #include "fhiclcpp/types/Atom.h"
36 #include "fhiclcpp/ParameterSet.h"
39 #include "CLHEP/Random/RandEngine.h"
50 namespace icarus::opdet {
154 Comment(
"simulated photons to be digitized (sim::SimPhotons)")
160 "parameters describing the single photon response"
161 " (SinglePhotonPulseFunctionTool tool)"
165 fhicl::TableFragment<icarus::opdet::PMTsimulationAlgMaker::Config>
algoConfig;
168 Name(
"WritePhotons"),
170 (
"writes the scintillation photon contributing to the waveforms"),
175 Name(
"EfficiencySeed"),
176 Comment(
"fix the seed for stochastic photon detection efficiency")
180 Name(
"DarkNoiseSeed"),
181 Comment(
"fix the seed for stochastic dark noise generation")
185 Name(
"ElectronicsNoiseSeed"),
186 Comment(
"fix the seed for stochastic electronics noise generation")
190 Name(
"ElectronicsNoiseRandomEngine"),
191 Comment(
"type of random engine to use for electronics noise"),
196 Name(
"DarkNoiseRandomEngine"),
197 Comment(
"type of random engine to use for dark noise"),
215 void produce(art::Event &
e)
override;
253 , fInputModuleName(config().inputModuleLabel())
254 , fWritePhotons(config().writePhotons())
255 , fSinglePhotonResponseFunc{
256 art::make_tool<icarus::opdet::SinglePhotonPulseFunctionTool>
257 (config().SinglePhotonResponse.get<fhicl::ParameterSet>())
260 , makePMTsimulator(config().algoConfig())
261 , fEfficiencyEngine(art::ServiceHandle<rndm::NuRandomService>()->createEngine
262 (*
this,
"HepJamesRandom",
"Efficiencies", config().EfficiencySeed)
264 , fDarkNoiseEngine(art::ServiceHandle<rndm::NuRandomService>()->createEngine(
266 config().darkNoiseRandomEngine(),
268 config().DarkNoiseSeed
270 , fElectronicsNoiseEngine(art::ServiceHandle<rndm::NuRandomService>()->createEngine(
272 config().electronicsNoiseRandomEngine(),
274 config().ElectronicsNoiseSeed
278 produces<std::vector<raw::OpDetWaveform>>();
279 if (fWritePhotons) produces<std::vector<sim::SimPhotons> >();
281 fNotFirstTime.clear();
288 mf::LogDebug(
"SimPMTIcarus") << e.id();
293 auto pulseVecPtr = std::make_unique< std::vector< raw::OpDetWaveform > > ();
295 std::unique_ptr<std::vector<sim::SimPhotons>> simphVecPtr;
297 simphVecPtr = std::make_unique< std::vector< sim::SimPhotons > > ();
302 art::Handle<std::vector<sim::SimPhotons> > pmtVector;
303 art::Handle<std::vector<sim::SimPhotonsLite> > pmtLiteVector;
305 if(!pmtVector.isValid())
306 pmtLiteVector = e.getHandle< std::vector<sim::SimPhotonsLite> >(
fInputModuleName);
308 auto const clockData =
309 art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
314 *(lar::providerFrom<detinfo::LArPropertiesService>()),
324 mf::LogDebug log {
"SimPMTIcarus" };
325 log <<
"PMT simulation configuration (first event):\n";
326 PMTsimulator->printConfiguration(log);
332 unsigned int nopch = 0;
333 if(pmtVector.isValid()) {
334 nopch = pmtVector->size();
335 for(
auto const& photons : *pmtVector) {
341 auto const& [ channelWaveforms, photons_used ]
342 = PMTsimulator->simulate(photons, lite_photons);
344 channelWaveforms.cbegin(), channelWaveforms.cend(),
345 std::back_inserter(*pulseVecPtr)
347 if (simphVecPtr && photons_used)
348 simphVecPtr->emplace_back(std::move(photons_used.value()));
352 else if(pmtLiteVector.isValid()) {
353 nopch = pmtLiteVector->size();
354 for(
auto const& lite_photons : *pmtLiteVector) {
360 auto const& [ channelWaveforms, photons_used ]
361 = PMTsimulator->simulate(photons, lite_photons);
363 channelWaveforms.cbegin(), channelWaveforms.cend(),
364 std::back_inserter(*pulseVecPtr)
370 mf::LogInfo(
"SimPMTIcarus") <<
"Generated " << pulseVecPtr->size()
371 <<
" waveforms out of " << nopch <<
" optical channels.";
376 e.put(std::move(pulseVecPtr));
377 if (simphVecPtr) e.put(std::move(simphVecPtr));
fhicl::Atom< std::string > electronicsNoiseRandomEngine
Simulates the digitization of ICARUS PMT response and trigger.
Utilities related to art service access.
rndm::SeedAtom EfficiencySeed
icarus::opdet::PMTsimulationAlgMaker makePMTsimulator
The actual simulation algorithm.
CLHEP::HepRandomEngine & fDarkNoiseEngine
Abstract interface of shape of a pulse from one photoelectron.
art::EDProducer::Table< Config > Parameters
fhicl::Atom< std::string > darkNoiseRandomEngine
icarus::opdet::SinglePhotonResponseFunc_t const SinglePhotonResponseFunc_t
Type of single photoelectron response function.
CLHEP::HepRandomEngine & fElectronicsNoiseEngine
std::atomic_flag fNotFirstTime
True if firstTime() has already been called.
rndm::SeedAtom DarkNoiseSeed
Simulation objects for optical detectors.
art::InputTag fInputModuleName
Input tag for simulated scintillation photons (or photoelectrons).
std::unique_ptr< SinglePhotonResponseFunc_t > const fSinglePhotonResponseFunc
Single photoelectron response function.
Interface for a function describing a pulse from a photoelectron.
BEGIN_PROLOG vertical distance to the surface Name
SimPMTIcarus(Parameters const &config)
Collection of photons which recorded on one channel.
Compact representation of photons on a channel.
SimPMTIcarus & operator=(SimPMTIcarus const &)=delete
Dimensioned variables representing space or time quantities.
CLHEP::HepRandomEngine & fEfficiencyEngine
Algorithms for the simulation of ICARUS PMT channels.
fhicl::TableFragment< icarus::opdet::PMTsimulationAlgMaker::Config > algoConfig
void produce(art::Event &e) override
fhicl::DelegatedParameter SinglePhotonResponse
fhicl::Atom< bool > writePhotons
bool fWritePhotons
Whether to save contributing photons.
bool firstTime()
Returns whether no other event has been processed yet.
fhicl::Atom< art::InputTag > inputModuleLabel
rndm::SeedAtom ElectronicsNoiseSeed
Returns a new PMTsimulationAlg with an updated configuration.