Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
opdet::SIPMOpSensorSim Class Reference
Inheritance diagram for opdet::SIPMOpSensorSim:
art::EDProducer art::detail::Producer art::detail::LegacyModule art::Modifier art::ModuleBase art::ProductRegistryHelper

Classes

struct  Config
 

Public Types

using Parameters = art::EDProducer::Table< Config >
 
- Public Types inherited from art::EDProducer
using ModuleType = EDProducer
 
using WorkerType = WorkerT< EDProducer >
 
- Public Types inherited from art::detail::Producer
template<typename UserConfig , typename KeysToIgnore = void>
using Table = Modifier::Table< UserConfig, KeysToIgnore >
 
- Public Types inherited from art::Modifier
template<typename UserConfig , typename UserKeysToIgnore = void>
using Table = ProducerTable< UserConfig, detail::ModuleConfig, UserKeysToIgnore >
 

Public Member Functions

 SIPMOpSensorSim (Parameters const &config)
 
void produce (art::Event &) override
 
- Public Member Functions inherited from art::EDProducer
 EDProducer (fhicl::ParameterSet const &pset)
 
template<typename Config >
 EDProducer (Table< Config > const &config)
 
std::string workerType () const
 
- Public Member Functions inherited from art::detail::Producer
virtual ~Producer () noexcept
 
 Producer (fhicl::ParameterSet const &)
 
 Producer (Producer const &)=delete
 
 Producer (Producer &&)=delete
 
Produceroperator= (Producer const &)=delete
 
Produceroperator= (Producer &&)=delete
 
void doBeginJob (SharedResources const &resources)
 
void doEndJob ()
 
void doRespondToOpenInputFile (FileBlock const &fb)
 
void doRespondToCloseInputFile (FileBlock const &fb)
 
void doRespondToOpenOutputFiles (FileBlock const &fb)
 
void doRespondToCloseOutputFiles (FileBlock const &fb)
 
bool doBeginRun (RunPrincipal &rp, ModuleContext const &mc)
 
bool doEndRun (RunPrincipal &rp, ModuleContext const &mc)
 
bool doBeginSubRun (SubRunPrincipal &srp, ModuleContext const &mc)
 
bool doEndSubRun (SubRunPrincipal &srp, ModuleContext const &mc)
 
bool doEvent (EventPrincipal &ep, ModuleContext const &mc, std::atomic< std::size_t > &counts_run, std::atomic< std::size_t > &counts_passed, std::atomic< std::size_t > &counts_failed)
 
- Public Member Functions inherited from art::Modifier
 ~Modifier () noexcept
 
 Modifier ()
 
 Modifier (Modifier const &)=delete
 
 Modifier (Modifier &&)=delete
 
Modifieroperator= (Modifier const &)=delete
 
Modifieroperator= (Modifier &&)=delete
 
- Public Member Functions inherited from art::ModuleBase
virtual ~ModuleBase () noexcept
 
 ModuleBase ()
 
ModuleDescription const & moduleDescription () const
 
void setModuleDescription (ModuleDescription const &)
 
std::array< std::vector< ProductInfo >, NumBranchTypes > const & getConsumables () const
 
void sortConsumables (std::string const &current_process_name)
 
template<typename T , BranchType BT>
ViewToken< T > consumesView (InputTag const &tag)
 
template<typename T , BranchType BT>
ViewToken< T > mayConsumeView (InputTag const &tag)
 

Private Member Functions

void PhotonsToPE (sim::OpDetBacktrackerRecord const &btr, sim::OpDetDivRec &dr_plusnoise)
 
void AddDarkNoise (sim::OpDetDivRec &)
 
unsigned short CrossTalk ()
 
void SetBeginEndTimes ()
 

Private Attributes

art::InputTag fInputTag
 
art::ProductToken< std::vector< sim::OpDetBacktrackerRecord > > fInputToken
 
double fQE
 
double fDarkNoiseRate
 
double fCrossTalk
 
double fTimeBegin
 
double fTimeEnd
 
bool fCorrectLateLight
 
double fLateLightCorrection
 
double fLateLightBoundary
 
CLHEP::HepRandomEngine & fSIPMEngine
 
CLHEP::RandExponential fRandExponential
 
CLHEP::RandFlat fRandFlat
 
CLHEP::RandPoissonQ fRandPoissPhot
 

Additional Inherited Members

- Static Public Member Functions inherited from art::EDProducer
static void commitEvent (EventPrincipal &ep, Event &e)
 
- Protected Member Functions inherited from art::ModuleBase
ConsumesCollectorconsumesCollector ()
 
template<typename T , BranchType = InEvent>
ProductToken< T > consumes (InputTag const &)
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > consumesView (InputTag const &)
 
template<typename T , BranchType = InEvent>
void consumesMany ()
 
template<typename T , BranchType = InEvent>
ProductToken< T > mayConsume (InputTag const &)
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > mayConsumeView (InputTag const &)
 
template<typename T , BranchType = InEvent>
void mayConsumeMany ()
 

Detailed Description

Definition at line 69 of file SIPMOpSensorSim_module.cc.

Member Typedef Documentation

Definition at line 85 of file SIPMOpSensorSim_module.cc.

Constructor & Destructor Documentation

opdet::SIPMOpSensorSim::SIPMOpSensorSim ( Parameters const &  config)
explicit

Definition at line 136 of file SIPMOpSensorSim_module.cc.

138  , fInputTag{ config().InputTag()}
139  , fInputToken{ consumes< std::vector<sim::OpDetBacktrackerRecord> >(fInputTag) }
141  , fCrossTalk{ config().CrossTalk()}
143  "HepJamesRandom",
144  "sipm",
145  config.get_PSet(),
146  "SeedSiPM"))
150  {
151 
152  // This module produces (infrastructure piece)
153  produces< std::vector< sim::OpDetDivRec > >();
154 
155 
156  if (fDarkNoiseRate < 0.0) {
158  << "fDarkNoiseRate: " << fDarkNoiseRate << '\n'
159  << "Dark noise rate should be non-negative!\n";
160  }
161 
162 
163  double tempQE = config().QuantumEfficiency() * config().Correction();
164  if (tempQE < 0 || tempQE > 1) {
166  << "QuantumEfficiency in SIPMSensorSim: " << config().QuantumEfficiency() << "\n"
167  << " with correction: " << config().Correction() << "\n"
168  << " leading to total efficiency: " << tempQE << "\n"
169  << "It should be between 0 and 1!\n";
170  }
171 
172  // Correct out the prescaling applied during simulation
173  auto const *LarProp = lar::providerFrom<detinfo::LArPropertiesService>();
174  fQE = tempQE / LarProp->ScintPreScale();
175 
176  if (fQE > 1.0001 ) {
178  << "QuantumEfficiency in SIPMSensorSim: " << config().QuantumEfficiency() << "\n"
179  << " with correction: " << config().Correction() << "\n"
180  << " leading to total efficiency: " << tempQE << "\n"
181  << "is too large.\n"
182  << "It is larger than the prescaling applied during simulation, " << LarProp->ScintPreScale() << ".\n"
183  << "Final QE must be equal to or smaller than the QE applied at simulation time.\n";
184  }
185 
186 
187  // Check for non-trivial channel mapping which is not supported
189  for (unsigned int opDet = 0; opDet < geometry->NOpDets() ; ++opDet) {
190  if (geometry->NOpHardwareChannels(opDet) > 1)
192  << "OpDet #" << opDet << " has " << geometry->NOpHardwareChannels(opDet)
193  << " channels associated with it. \n"
194  << "This kind of channel mapping is not supported by SIPMOpSensorSim.\n"
195  << "You need to use the legacy OpDetDigitizerDUNE instead.\n";
196  }
197 
198  // Set time ranges if needed for dark noise
199  if (fDarkNoiseRate > 0) SetBeginEndTimes();
200 
201  // Check for optional parameters for adjusting late light.
202  // Apply adjustments if both are given.
203  // Throw an error if only one is specified.
204  bool haveCorrection = config().LateLightCorrection(fLateLightCorrection);
205  bool haveBoundary = config().LateLightBoundary(fLateLightBoundary);
206  fCorrectLateLight = haveBoundary && haveCorrection;
207 
208  if (haveBoundary != haveCorrection) {
210  << "Must specify both LateLightCorrection and LateLightBoundary in order to apply correction.\n"
211  << "Leave both out to not adjust late light.\n";
212  }
213 
214  if (fCorrectLateLight && fLateLightCorrection*tempQE > LarProp->ScintPreScale())
215  {
217  << "QuantumEfficiency in SIPMSensorSim: " << config().QuantumEfficiency() << "\n"
218  << " with correction: " << config().Correction() << "\n"
219  << " and late light correction: " << fLateLightCorrection << "\n"
220  << " leading to total efficiency: " << tempQE * fLateLightCorrection << "\n"
221  << "is too large.\n"
222  << "It is larger than the prescaling applied during simulation, " << LarProp->ScintPreScale() << ".\n"
223  << "Final QE must be equal to or smaller than the QE applied at simulation time.\n";
224  }
225  }
base_engine_t & createEngine(seed_t seed)
CLHEP::HepRandomEngine & fSIPMEngine
fhicl::Atom< art::InputTag > InputTag
unsigned int NOpHardwareChannels(int opDet) const
fhicl::OptionalAtom< double > LateLightCorrection
static Config * config
Definition: config.cpp:1054
CLHEP::RandPoissonQ fRandPoissPhot
art::ProductToken< std::vector< sim::OpDetBacktrackerRecord > > fInputToken
unsigned int NOpDets() const
Number of OpDets in the whole detector.
fhicl::OptionalAtom< double > LateLightBoundary
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
CLHEP::RandExponential fRandExponential

Member Function Documentation

void opdet::SIPMOpSensorSim::AddDarkNoise ( sim::OpDetDivRec dr_plusnoise)
private

Definition at line 314 of file SIPMOpSensorSim_module.cc.

315  {
316 
317  double tau = 1.0/fDarkNoiseRate*1.e6; // Typical time between Dark counts in us
318  // Multiply by 10^6 since fDarkNoiseRate is in Hz
319 
320  double darkNoiseTime = fRandExponential.fire(tau) + fTimeBegin;
321  while (darkNoiseTime < fTimeEnd) {
322  //Currently using all zeros as an indicator of Dark Noise for the trackID.
323  int PE = 1+CrossTalk();
324  for(int j = 0; j < PE; j++) {
325  dr_plusnoise.AddPhoton(dr_plusnoise.OpDetNum(), 0, darkNoiseTime);
326  }
327 
328  // Find next time to simulate a single PE pulse
329  darkNoiseTime += fRandExponential.fire(tau);
330  }
331  }
int OpDetNum() const
Definition: OpDetDivRec.h:102
CLHEP::RandExponential fRandExponential
void AddPhoton(int opchan, int tid, OpDet_Time_Chans::stored_time_t pdTime)
Definition: OpDetDivRec.cxx:25
unsigned short opdet::SIPMOpSensorSim::CrossTalk ( )
private

Definition at line 305 of file SIPMOpSensorSim_module.cc.

306  {
307  // Use recursion to allow cross talk to create cross talk
308  if (fCrossTalk <= 0.0) return 0;
309  else if (fRandFlat.fire(1.0) > fCrossTalk) return 0;
310  else return 1+CrossTalk();
311  }
void opdet::SIPMOpSensorSim::PhotonsToPE ( sim::OpDetBacktrackerRecord const &  btr,
sim::OpDetDivRec dr_plusnoise 
)
private

Definition at line 257 of file SIPMOpSensorSim_module.cc.

259  {
260  // Don't do anything without any records
261  if (btr.timePDclockSDPsMap().size() == 0)
262  return;
263 
264  // Get the earliest time in the BTR
265  double firstTime = btr.timePDclockSDPsMap()[0].first;
266  if (fCorrectLateLight) {
267  for (auto time_sdps : btr.timePDclockSDPsMap()) {
268  double time = btr.timePDclockSDPsMap()[0].first;
269  if (time < firstTime) firstTime = time;
270  }
271  }
272 
273  // Loop through times in vector< pair< arrival time (in ns), vector< SDP > > >
274  for (auto const& [time, sdps]: btr.timePDclockSDPsMap()) {
275 
276  double lateScale = 1.;
277  if (fCorrectLateLight) {
278  if (time > firstTime + fLateLightBoundary)
279  lateScale = fLateLightCorrection;
280  }
281 
282  // Loop through SDPs
283  for(auto const& sdp : sdps) {
284 
285  // Reduce true photons by QE, poisson-fluctuate
286  int nphot = fRandPoissPhot.fire(fQE * (double)sdp.numPhotons * lateScale);
287 
288  // For each true photon detected
289  for(int truePh=0; truePh<nphot; ++truePh) {
290 
291  // Determine actual PE with Cross Talk
292  unsigned int PE = 1+CrossTalk();
293  for(unsigned int i = 0; i < PE; i++) {
294  // Add to collection
295  dr_plusnoise.AddPhoton(btr.OpDetNum(), // Channel
296  sdp.trackID, // TrackID
297  time); // Time
298  }
299  }
300  }
301  }
302  }
CLHEP::RandPoissonQ fRandPoissPhot
void AddPhoton(int opchan, int tid, OpDet_Time_Chans::stored_time_t pdTime)
Definition: OpDetDivRec.cxx:25
void opdet::SIPMOpSensorSim::produce ( art::Event event)
overridevirtual

Implements art::EDProducer.

Definition at line 229 of file SIPMOpSensorSim_module.cc.

230  {
231  // A pointer that will store produced OpDetDivRec
232  auto OpDetDivRecPtr = std::make_unique< std::vector< sim::OpDetDivRec > >();
233 
234  // Get OpDetBacktrackerRecord from the event
235  auto const & btr_handle = event.getValidHandle(fInputToken);
236 
237  // For every optical detector:
238  for (auto const& btr : *btr_handle) {
239  int opDet = btr.OpDetNum();
240 
241  auto DivRecPlusNoise = sim::OpDetDivRec(opDet);
242 
243  PhotonsToPE(btr, DivRecPlusNoise);
244 
245  // Generate dark noise
246  if (fDarkNoiseRate > 0.0) AddDarkNoise(DivRecPlusNoise);
247 
248  // AddAfterPulsing();
249 
250  OpDetDivRecPtr->emplace_back(DivRecPlusNoise);
251  }
252 
253  event.put(std::move(OpDetDivRecPtr));
254  }
def move(depos, offset)
Definition: depos.py:107
void AddDarkNoise(sim::OpDetDivRec &)
art::ProductToken< std::vector< sim::OpDetBacktrackerRecord > > fInputToken
void PhotonsToPE(sim::OpDetBacktrackerRecord const &btr, sim::OpDetDivRec &dr_plusnoise)
void opdet::SIPMOpSensorSim::SetBeginEndTimes ( )
private

Definition at line 334 of file SIPMOpSensorSim_module.cc.

335  {
336 
337  // Get the window start/end time from the detector properties services
338  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
339  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob(clockData);
340  auto const geometry = art::ServiceHandle< geo::Geometry >();
341 
342  double maxDrift = 0.0;
343  for (geo::TPCGeo const& tpc : geometry->IterateTPCs())
344  if (maxDrift < tpc.DriftDistance()) maxDrift = tpc.DriftDistance();
345 
346  // Start at -1 drift window
347  fTimeBegin = -1*maxDrift/detProp.DriftVelocity();
348 
349  // Take the TPC readout window size and convert
350  // to us with the electronics clock frequency
351  fTimeEnd = detProp.ReadOutWindowSize() / clockData.TPCClock().Frequency();
352  }
Geometry information for a single TPC.
Definition: TPCGeo.h:38

Member Data Documentation

bool opdet::SIPMOpSensorSim::fCorrectLateLight
private

Definition at line 103 of file SIPMOpSensorSim_module.cc.

double opdet::SIPMOpSensorSim::fCrossTalk
private

Definition at line 97 of file SIPMOpSensorSim_module.cc.

double opdet::SIPMOpSensorSim::fDarkNoiseRate
private

Definition at line 96 of file SIPMOpSensorSim_module.cc.

art::InputTag opdet::SIPMOpSensorSim::fInputTag
private

Definition at line 93 of file SIPMOpSensorSim_module.cc.

art::ProductToken< std::vector<sim::OpDetBacktrackerRecord> > opdet::SIPMOpSensorSim::fInputToken
private

Definition at line 94 of file SIPMOpSensorSim_module.cc.

double opdet::SIPMOpSensorSim::fLateLightBoundary
private

Definition at line 105 of file SIPMOpSensorSim_module.cc.

double opdet::SIPMOpSensorSim::fLateLightCorrection
private

Definition at line 104 of file SIPMOpSensorSim_module.cc.

double opdet::SIPMOpSensorSim::fQE
private

Definition at line 95 of file SIPMOpSensorSim_module.cc.

CLHEP::RandExponential opdet::SIPMOpSensorSim::fRandExponential
private

Definition at line 109 of file SIPMOpSensorSim_module.cc.

CLHEP::RandFlat opdet::SIPMOpSensorSim::fRandFlat
private

Definition at line 110 of file SIPMOpSensorSim_module.cc.

CLHEP::RandPoissonQ opdet::SIPMOpSensorSim::fRandPoissPhot
private

Definition at line 111 of file SIPMOpSensorSim_module.cc.

CLHEP::HepRandomEngine& opdet::SIPMOpSensorSim::fSIPMEngine
private

Definition at line 108 of file SIPMOpSensorSim_module.cc.

double opdet::SIPMOpSensorSim::fTimeBegin
private

Definition at line 99 of file SIPMOpSensorSim_module.cc.

double opdet::SIPMOpSensorSim::fTimeEnd
private

Definition at line 100 of file SIPMOpSensorSim_module.cc.


The documentation for this class was generated from the following file: