DUNEOpDetResponse_service.cc
Go to the documentation of this file.
1 // -*- mode: c++; c-basic-offset: 4; -*-
2 ////////////////////////////////////////////////////////////////////////
3 //
4 // \file DUNEOpDetResponse_service.cc
5 //
6 ////////////////////////////////////////////////////////////////////////
7 
10 #include "TGeoNode.h"
11 #include "TGeoBBox.h"
15 #include "CLHEP/Random/RandFlat.h"
16 #include <boost/algorithm/string.hpp>
17 
18 namespace opdet{
19 
20 
21  //--------------------------------------------------------------------
23  art::ActivityRegistry &/*reg*/)
24  {
25  this->doReconfigure(pset);
26  }
27 
28  //--------------------------------------------------------------------
30  { }
31 
32 
33  //--------------------------------------------------------------------
35  {
36  double tempfQE = pset.get<double>("QuantumEfficiency");
37  fWavelengthCutLow = pset.get<double>("WavelengthCutLow");
38  fWavelengthCutHigh = pset.get<double>("WavelengthCutHigh");
39  fLightGuideAttenuation = pset.get<bool>("LightGuideAttenuation");
40  lambdaShort = pset.get<double>("LambdaShort");
41  lambdaLong = pset.get<double>("LambdaLong");
42  fracShort = pset.get<double>("FracShort");
43  fracLong = pset.get<double>("FracLong");
44  fChannelConversion = pset.get<std::string>("ChannelConversion");
45  std::string tmpAxis = pset.get<std::string>("LongAxis");
46 
47  boost::algorithm::to_lower(tmpAxis);
48 
49  if (tmpAxis == "x") fLongAxis = 0;
50  if (tmpAxis == "y") fLongAxis = 1;
51  if (tmpAxis == "z") fLongAxis = 2;
52 
53  // Only allow channel conversion once - so it must be set to happen
54  // either during full simulation (library generation) or during
55  // fast simulation (library use).
56 
57  boost::algorithm::to_lower(fChannelConversion);
58 
59  fFullSimChannelConvert = false;
60  fFastSimChannelConvert = false;
61 
62  if (fChannelConversion == "full") fFullSimChannelConvert = true;
63  if (fChannelConversion == "fast") fFastSimChannelConvert = true;
64 
65  // Correct out the prescaling applied during simulation
66  auto const *LarProp = lar::providerFrom<detinfo::LArPropertiesService>();
67  fQE = tempfQE / LarProp->ScintPreScale();
68 
69  if (fQE > 1.0001 ) {
70  mf::LogError("DUNEOpDetResponse_service") << "Quantum efficiency set in OpDetResponse_service, " << tempfQE
71  << " is too large. It is larger than the prescaling applied during simulation, "
72  << LarProp->ScintPreScale()
73  << " (fQE="
74  << fQE
75  << "). Final QE must be equal to or smaller than the QE applied at simulation time.";
76  std::abort();
77  }
78 
79  }
80 
81 
82  //--------------------------------------------------------------------
84  {
87  return geom->NOpChannels();
88  else
89  return geom->NOpDets();
90 
91  }
92 
93 
94  //--------------------------------------------------------------------
95  bool DUNEOpDetResponse::doDetected(int OpDet, const sim::OnePhoton& Phot, int &newOpChannel) const
96  {
97 
98  // Find the Optical Detector using the geometry service
100 
101 
103  // Override default number of channels for Fiber and Plank
104  float NOpHardwareChannels = geom->NOpHardwareChannels(OpDet);
105  int hardwareChannel = (int) ( CLHEP::RandFlat::shoot(1.0) * NOpHardwareChannels );
106  newOpChannel = geom->OpChannel(OpDet, hardwareChannel);
107  }
108  else{
109  newOpChannel = OpDet;
110  }
111 
112  // Check QE
113  if ( CLHEP::RandFlat::shoot(1.0) > fQE ) return false;
114 
115  double wavel = wavelength(Phot.Energy);
116  // Check wavelength acceptance
117  if (wavel < fWavelengthCutLow) return false;
118  if (wavel > fWavelengthCutHigh) return false;
119 
121  // Get the length of the photon detector
122  const TGeoNode* node = geom->OpDetGeoFromOpDet(OpDet).Node();
123  TGeoBBox *box = (TGeoBBox*)node->GetVolume()->GetShape();
124  double opdetLength = 0;
125  double sipmDistance = 0;
126 
127  if (fLongAxis == 0) {
128  opdetLength = box->GetDX();
129  sipmDistance = opdetLength - Phot.FinalLocalPosition.x();
130  }
131  else if (fLongAxis == 1) {
132  opdetLength = box->GetDY();
133  sipmDistance = opdetLength - Phot.FinalLocalPosition.y();
134  }
135  else if (fLongAxis == 2) {
136  opdetLength = box->GetDZ();
137  sipmDistance = opdetLength - Phot.FinalLocalPosition.z();
138  }
139  else {
140  mf::LogError("DUNEOpDetResponse") << "Unknown axis, fLongAxis = " << fLongAxis;
141  std::abort();
142  }
143 
144 
145 
146  // Throw away some photons based on attenuation
147  double AttenuationProb = fracShort*exp(-sipmDistance/lambdaShort) + fracLong*exp(-sipmDistance/lambdaLong);
148 
149  //mf::LogVerbatim("DUNEOpDetResponse") << "OpDet: " << OpDet
150  // << " has length " << opdetLength << " in detector "
151  // << box->GetDX() << " x " << box->GetDY() << " x " << box->GetDZ();
152  //mf::LogVerbatim("DUNEOpDetResponse") << " Local Position = (" << Phot.FinalLocalPosition.x()
153  // << ", " << Phot.FinalLocalPosition.y() << ", " << Phot.FinalLocalPosition.z() << ")";
154  //mf::LogVerbatim("DUNEOpDetResponse") << " Distance to SiPM = " << sipmDistance << " along axis " << fLongAxis;
155  //mf::LogVerbatim("DUNEOpDetResponse") << " Attenuation Probability = " << AttenuationProb;
156 
157  if ( CLHEP::RandFlat::shoot(1.0) > AttenuationProb ) return false;
158 
159 
160  }
161 
162  return true;
163  }
164 
165  //--------------------------------------------------------------------
166  bool DUNEOpDetResponse::doDetectedLite(int OpDet, int &newOpChannel) const
167  {
169 
170  // Find the Optical Detector using the geometry service
172  // Here OpDet must be opdet since we are introducing
173  // channel mapping here.
174  float NOpHardwareChannels = geom->NOpHardwareChannels(OpDet);
175  int hardwareChannel = (int) ( CLHEP::RandFlat::shoot(1.0) * NOpHardwareChannels );
176  newOpChannel = geom->OpChannel(OpDet, hardwareChannel);
177  }
178  else{
179  newOpChannel = OpDet;
180  }
181 
182  // Check QE
183  if ( CLHEP::RandFlat::shoot(1.0) > fQE ) return false;
184 
185 
186  return true;
187  }
188 
189  //--------------------------------------------------------------------
190  bool DUNEOpDetResponse::doDetectedLiteWithChannel(int OpDet, int &newOpChannel, int &hardwareChannel) const
191  {
193 
194  // Find the Optical Detector using the geometry service
196  // Here OpDet must be opdet since we are introducing
197  // channel mapping here.
198  float NOpHardwareChannels = geom->NOpHardwareChannels(OpDet);
199  hardwareChannel = (int) ( CLHEP::RandFlat::shoot(1.0) * NOpHardwareChannels );
200  newOpChannel = geom->OpChannel(OpDet, hardwareChannel);
201  }
202  else{
203  newOpChannel = OpDet;
204  }
205 
206  // Check QE
207  if ( CLHEP::RandFlat::shoot(1.0) > fQE ) return false;
208 
209 
210  return true;
211  }
212 
213 
214 } // namespace
215 
const TGeoNode * Node() const
Returns the ROOT object describing the detector geometry.
Definition: OpDetGeo.h:146
OpDetGeo const & OpDetGeoFromOpDet(unsigned int OpDet) const
Returns the geo::OpDetGeo object for the given detector number.
std::string string
Definition: nybbler.cc:12
All information of a photon entering the sensitive optical detector volume.
Definition: SimPhotons.h:64
unsigned int NOpHardwareChannels(int opDet) const
bool doDetectedLiteWithChannel(int OpDet, int &newOpChannel, int &hardwareChannel) const
virtual bool doDetected(int OpDet, const sim::OnePhoton &Phot, int &newOpChannel) const
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
unsigned int NOpChannels() const
Number of electronics channels for all the optical detectors.
virtual void doReconfigure(fhicl::ParameterSet const &p)
T get(std::string const &key) const
Definition: ParameterSet.h:271
unsigned int NOpDets() const
Number of OpDets in the whole detector.
unsigned int OpChannel(int detNum, int hardwareChannel) const
Convert detector number and hardware channel to unique channel.
Encapsulate the geometry of an optical detector.
DUNEOpDetResponse(fhicl::ParameterSet const &pset, art::ActivityRegistry &reg)
Index NOpHardwareChannels(Index opDet)
geo::OpticalPoint_t FinalLocalPosition
Where photon enters the optical detector in local coordinates [cm].
Definition: SimPhotons.h:75
virtual bool doDetectedLite(int OpDet, int &newOpChannel) const
float Energy
Scintillation photon energy [GeV].
Definition: SimPhotons.h:82
virtual float wavelength(double energy) const
#define DEFINE_ART_SERVICE_INTERFACE_IMPL(svc, iface)