LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
larg4::OpFastScintillation Class Reference

#include "OpFastScintillation.hh"

Inheritance diagram for larg4::OpFastScintillation:

Classes

struct  Dims
 
struct  OpticalDetector
 

Public Member Functions

 OpFastScintillation (const G4String &processName="Scintillation", G4ProcessType type=fElectromagnetic)
 
 ~OpFastScintillation ()
 
virtual G4bool IsApplicable (const G4ParticleDefinition &aParticleType)
 
G4double GetMeanFreePath (const G4Track &aTrack, G4double, G4ForceCondition *)
 
G4double GetMeanLifeTime (const G4Track &aTrack, G4ForceCondition *)
 
virtual G4VParticleChange * PostStepDoIt (const G4Track &aTrack, const G4Step &aStep)
 
virtual G4VParticleChange * AtRestDoIt (const G4Track &aTrack, const G4Step &aStep)
 
void SetTrackSecondariesFirst (const G4bool state)
 
void SetFiniteRiseTime (const G4bool state)
 
G4bool GetTrackSecondariesFirst () const
 
G4bool GetFiniteRiseTime () const
 
void SetScintillationYieldFactor (const G4double yieldfactor)
 
G4double GetScintillationYieldFactor () const
 
void SetScintillationExcitationRatio (const G4double excitationratio)
 
G4double GetScintillationExcitationRatio () const
 
G4PhysicsTable * GetFastIntegralTable () const
 
G4PhysicsTable * GetSlowIntegralTable () const
 
void AddSaturation (G4EmSaturation *sat)
 
void RemoveSaturation ()
 
G4EmSaturation * GetSaturation () const
 
void SetScintillationByParticleType (const G4bool)
 
G4bool GetScintillationByParticleType () const
 
void DumpPhysicsTable () const
 
void getVUVTimes (std::vector< double > &arrivalTimes, const double distance_in_cm, const size_t angle_bin)
 
void generateParam (const size_t index, const size_t angle_bin)
 
void getVISTimes (std::vector< double > &arrivalTimes, const TVector3 &ScintPoint, const TVector3 &OpDetPoint)
 
void detectedDirectHits (std::map< size_t, int > &DetectedNum, const double Num, geo::Point_t const &ScintPoint) const
 
void detectedReflecHits (std::map< size_t, int > &ReflDetectedNum, const double Num, geo::Point_t const &ScintPoint) const
 

Protected Member Functions

void BuildThePhysicsTable ()
 
bool RecordPhotonsProduced (const G4Step &aStep, double N)
 

Protected Attributes

std::unique_ptr< G4PhysicsTable > theSlowIntegralTable
 
std::unique_ptr< G4PhysicsTable > theFastIntegralTable
 
G4bool fTrackSecondariesFirst
 
G4bool fFiniteRiseTime
 
G4double YieldFactor
 
G4double ExcitationRatio
 
G4bool scintillationByParticleType
 

Private Member Functions

bool usesSemiAnalyticModel () const
 Returns whether the semi-analytic visibility parametrization is being used. More...
 
int VUVHits (const double Nphotons_created, geo::Point_t const &ScintPoint, OpticalDetector const &opDet) const
 
int VISHits (geo::Point_t const &ScintPoint, OpticalDetector const &opDet, const double cathode_hits_rec, const std::array< double, 3 > hotspot) const
 
G4double single_exp (const G4double t, const G4double tau2) const
 
G4double bi_exp (const G4double t, const G4double tau1, const G4double tau2) const
 
G4double scint_time (const G4Step &aStep, G4double ScintillationTime, G4double ScintillationRiseTime) const
 
void propagationTime (std::vector< double > &arrival_time_dist, G4ThreeVector x0, const size_t OpChannel, bool Reflected=false)
 
G4double sample_time (const G4double tau1, const G4double tau2) const
 
double reemission_energy () const
 
void average_position (G4Step const &aStep, double *xzyPos) const
 
double Rectangle_SolidAngle (const double a, const double b, const double d) const
 
double Rectangle_SolidAngle (Dims const &o, const std::array< double, 3 > v) const
 
double Disk_SolidAngle (const double d, const double h, const double b) const
 
double Omega_Dome_Model (const double distance, const double theta) const
 
G4double Gaisser_Hillas (const double x, const double *par) const
 
void ProcessStep (const G4Step &step)
 
bool isOpDetInSameTPC (geo::Point_t const &ScintPoint, geo::Point_t const &OpDetPoint) const
 
bool isScintInActiveVolume (geo::Point_t const &ScintPoint)
 
double interpolate (const std::vector< double > &xData, const std::vector< double > &yData, double x, bool extrapolate, size_t i=0) const
 
void interpolate3 (std::array< double, 3 > &inter, const std::vector< double > &xData, const std::vector< double > &yData1, const std::vector< double > &yData2, const std::vector< double > &yData3, double x, bool extrapolate) const
 

Static Private Member Functions

static std::vector< geo::BoxBoundedGeoextractActiveVolumes (geo::GeometryCore const &geom)
 

Private Attributes

std::map< double, double > tpbemission
 
std::unique_ptr< CLHEP::RandGeneral > fTPBEm
 
G4EmSaturation * emSaturation
 
phot::MappedFunctions_t ParPropTimeTF1
 
phot::MappedT0s_t ReflT0s
 
double fstep_size
 
double fmin_d
 
double fmax_d
 
double fvuv_vgroup_mean
 
double fvuv_vgroup_max
 
double finflexion_point_distance
 
double fangle_bin_timing_vuv
 
std::vector< std::vector< double > > fparameters [7]
 
std::vector< std::vector< TF1 > > VUV_timing
 
std::vector< std::vector< double > > VUV_max
 
std::vector< std::vector< double > > VUV_min
 
double fvis_vmean
 
double fangle_bin_timing_vis
 
std::vector< double > fdistances_refl
 
std::vector< double > fradial_distances_refl
 
std::vector< std::vector< std::vector< double > > > fcut_off_pars
 
std::vector< std::vector< std::vector< double > > > ftau_pars
 
double fdelta_angulo_vuv
 
bool fIsFlatPDCorr
 
std::vector< std::vector< double > > fGHvuvpars_flat
 
std::vector< double > fborder_corr_angulo_flat
 
std::vector< std::vector< double > > fborder_corr_flat
 
bool fIsDomePDCorr
 
std::vector< std::vector< double > > fGHvuvpars_dome
 
std::vector< double > fborder_corr_angulo_dome
 
std::vector< std::vector< double > > fborder_corr_dome
 
bool fStoreReflected
 
double fdelta_angulo_vis
 
std::vector< double > fvis_distances_x_flat
 
std::vector< double > fvis_distances_r_flat
 
std::vector< std::vector< std::vector< double > > > fvispars_flat
 
std::vector< double > fvis_distances_x_dome
 
std::vector< double > fvis_distances_r_dome
 
std::vector< std::vector< std::vector< double > > > fvispars_dome
 
double fplane_depth
 
double fcathode_zdimension
 
double fcathode_ydimension
 
geo::Point_t fcathode_centre
 
std::vector< geo::BoxBoundedGeo > const fActiveVolumes
 
double fradius
 
Dims fcathode_plane
 
int fL_abs_vuv
 
std::vector< geo::Point_tfOpDetCenter
 
std::vector< int > fOpDetType
 
std::vector< double > fOpDetLength
 
std::vector< double > fOpDetHeight
 
bool const bPropagate
 Whether propagation of photons is enabled. More...
 
phot::PhotonVisibilityService const *const fPVS
 Photon visibility service instance. More...
 
bool const fUseNhitsModel = false
 Whether the semi-analytic model is being used for photon visibility. More...
 
bool const fOnlyActiveVolume = false
 Whether photon propagation is performed only from active volumes. More...
 
bool const fOnlyOneCryostat = false
 
bool const fOpaqueCathode = false
 Whether the cathodes are fully opaque; currently hard coded "no". More...
 

Detailed Description

Definition at line 130 of file OpFastScintillation.hh.

Constructor & Destructor Documentation

larg4::OpFastScintillation::OpFastScintillation ( const G4String processName = "Scintillation",
G4ProcessType  type = fElectromagnetic 
)

Definition at line 180 of file OpFastScintillation.cxx.

References util::abs(), bPropagate, BuildThePhysicsTable(), art::errors::Configuration, util::counter(), emSaturation, util::enumerate(), ExcitationRatio, extractActiveVolumes(), fActiveVolumes, fangle_bin_timing_vis, fangle_bin_timing_vuv, fborder_corr_angulo_dome, fborder_corr_angulo_flat, fborder_corr_dome, fborder_corr_flat, fcathode_centre, fcathode_plane, fcathode_ydimension, fcathode_zdimension, fcut_off_pars, fdelta_angulo_vis, fdelta_angulo_vuv, fdistances_refl, fFiniteRiseTime, fGHvuvpars_dome, fGHvuvpars_flat, finflexion_point_distance, fIsDomePDCorr, fIsFlatPDCorr, fL_abs_vuv, fmax_d, fmin_d, fOnlyActiveVolume, fOnlyOneCryostat, fOpDetCenter, fOpDetHeight, fOpDetLength, fOpDetType, fparameters, fplane_depth, fPVS, fradial_distances_refl, fradius, fstep_size, fStoreReflected, ftau_pars, fTPBEm, fTrackSecondariesFirst, fUseNhitsModel, fvis_distances_r_dome, fvis_distances_r_flat, fvis_distances_x_dome, fvis_distances_x_flat, fvis_vmean, fvispars_dome, fvispars_flat, fvuv_vgroup_max, fvuv_vgroup_mean, geo::TPCGeo::GetCathodeCenter(), geo::OpDetGeo::GetCenter(), larg4::OpFastScintillation::Dims::h, geo::OpDetGeo::Height(), phot::PhotonVisibilityService::IncludePropTime(), interpolate(), geo::OpDetGeo::isBar(), geo::OpDetGeo::Length(), phot::PhotonVisibilityService::LoadGHDome(), phot::PhotonVisibilityService::LoadGHFlat(), phot::PhotonVisibilityService::LoadTimingsForVISPar(), phot::PhotonVisibilityService::LoadTimingsForVUVPar(), phot::PhotonVisibilityService::LoadVisParsDome(), phot::PhotonVisibilityService::LoadVisParsFlat(), phot::PhotonVisibilityService::LoadVisSemiAnalyticProperties(), phot::PhotonVisibilityService::LoadVUVSemiAnalyticProperties(), geo::GeometryCore::Ncryostats(), phot::PhotonVisibilityService::NOpChannels(), geo::GeometryCore::OpDetGeoFromOpDet(), detinfo::LArProperties::ScintByParticleType(), scintillationByParticleType, geo::OpDetGeo::Shape(), phot::PhotonVisibilityService::StoreReflected(), tpbemission, geo::GeometryCore::TPC(), phot::PhotonVisibilityService::UseNhitsModel(), usesSemiAnalyticModel(), lar::dump::vector(), VUV_max, VUV_min, VUV_timing, larg4::OpFastScintillation::Dims::w, and YieldFactor.

181  : G4VRestDiscreteProcess(processName, type)
182  , fActiveVolumes{extractActiveVolumes(*(lar::providerFrom<geo::Geometry>()))}
183  , bPropagate(!(art::ServiceHandle<sim::LArG4Parameters const>()->NoPhotonPropagation()))
186  // for now, limit to the active volume only if semi-analytic model is used
188  {
189  SetProcessSubType(25); // TODO: unhardcode
190  fTrackSecondariesFirst = false;
191  fFiniteRiseTime = false;
192  YieldFactor = 1.0;
193  ExcitationRatio = 1.0;
194 
195  const detinfo::LArProperties* larp = lar::providerFrom<detinfo::LArPropertiesService>();
196 
198 
199  if (verboseLevel > 0) { G4cout << GetProcessName() << " is created " << G4endl; }
200 
202  emSaturation = NULL;
203 
204  if (bPropagate) {
205  assert(fPVS);
206 
207  // Loading the position of each optical channel, neccessary for the parametrizatiuons of Nhits and prop-time
208  geo::GeometryCore const& geom = *(lar::providerFrom<geo::Geometry>());
209 
210  {
211  auto log = mf::LogTrace("OpFastScintillation")
212  << "OpFastScintillation: active volume boundaries from " << fActiveVolumes.size()
213  << " volumes:";
214  for (auto const& [iCryo, box] : util::enumerate(fActiveVolumes)) {
215  log << "\n - C:" << iCryo << ": " << box.Min() << " -- " << box.Max() << " cm";
216  } // for
217  log << "\n (scintillation photons are propagated "
218  << (fOnlyActiveVolume ? "only from active volumes" : "from anywhere") << ")";
219  } // local scope
220 
221  if (usesSemiAnalyticModel() && (geom.Ncryostats() > 1U)) {
222  if (fOnlyOneCryostat) {
223  mf::LogWarning("OpFastScintillation")
224  << std::string(80, '=') << "\nA detector with " << geom.Ncryostats()
225  << " cryostats is configured"
226  << " , and semi-analytic model is requested for scintillation photon propagation."
227  << " THIS CONFIGURATION IS NOT SUPPORTED and it is open to bugs"
228  << " (e.g. scintillation may be detected only in cryostat #0)."
229  << "\nThis would be normally a fatal error, but it has been forcibly overridden."
230  << "\n"
231  << std::string(80, '=');
232  }
233  else {
235  << "Photon propagation via semi-analytic model is not supported yet"
236  << " on detectors with more than one cryostat.";
237  }
238  } // if
239 
240  geo::Point_t const Cathode_centre{geom.TPC().GetCathodeCenter().X(),
241  fActiveVolumes[0].CenterY(),
242  fActiveVolumes[0].CenterZ()};
243  mf::LogTrace("OpFastScintillation") << "Cathode_centre: " << Cathode_centre << " cm";
244 
245  // std::cout << "\nInitialize acos_arr with " << acos_bins+1
246  // << " hence with a resolution of " << 1./acos_bins << std::endl;
247  // for(size_t i=0; i<=acos_bins; ++i){
248  // acos_arr[i] = std::acos(i/double(acos_bins));
249  // }
250 
251  for (size_t const i : util::counter(fPVS->NOpChannels())) {
252  geo::OpDetGeo const& opDet = geom.OpDetGeoFromOpDet(i);
253  fOpDetCenter.push_back(opDet.GetCenter());
254 
255  if (dynamic_cast<TGeoSphere const*>(opDet.Shape()) != nullptr) { // sphere/dome
256  fOpDetType.push_back(1); // Dome PMTs
257  fOpDetLength.push_back(-1);
258  fOpDetHeight.push_back(-1);
259  }
260  else if (opDet.isBar()) { // box
261  fOpDetType.push_back(0); //Arapucas
262  fOpDetLength.push_back(opDet.Length());
263  fOpDetHeight.push_back(opDet.Height());
264  }
265  else { // disk
266  fOpDetType.push_back(2); // Disk PMTs
267  // std::cout<<"Radio: "<<geom.OpDetGeoFromOpDet(i).RMax()<<std::endl;
268  fOpDetLength.push_back(-1);
269  fOpDetHeight.push_back(-1);
270  }
271  }
272 
273  if (fPVS->IncludePropTime()) {
274  std::cout << "Using parameterisation of timings." << std::endl;
275  //OLD VUV time parapetrization (to be removed soon)
276  //fPVS->SetDirectLightPropFunctions(functions_vuv, fd_break, fd_max, ftf1_sampling_factor);
277  //fPVS->SetReflectedCOLightPropFunctions(functions_vis, ft0_max, ft0_break_point);
278  //New VUV time parapetrization
280  fstep_size,
281  fmax_d,
282  fmin_d,
287 
288  // create vector of empty TF1s that will be replaces with the parameterisations that are generated as they are required
289  // default TF1() constructor gives function with 0 dimensions, can then check numDim to qucikly see if a parameterisation has been generated
290  const size_t num_params =
291  (fmax_d - fmin_d) /
292  fstep_size; // for d < fmin_d, no parameterisaton, a delta function is used instead
293  size_t num_angles = std::round(90 / fangle_bin_timing_vuv);
294  VUV_timing = std::vector(num_angles, std::vector(num_params, TF1()));
295 
296  // initialise vectors to contain range parameterisations sampled to in each case
297  // when using TF1->GetRandom(xmin,xmax), must be in same range otherwise sampling is regenerated, this is the slow part!
298  VUV_max = std::vector(num_angles, std::vector(num_params, 0.0));
299  VUV_min = std::vector(num_angles, std::vector(num_params, 0.0));
300 
301  // VIS time parameterisation
302  if (fPVS->StoreReflected()) {
303  // load parameters
307  ftau_pars,
308  fvis_vmean,
310  }
311  }
312  if (usesSemiAnalyticModel()) {
313  mf::LogVerbatim("OpFastScintillation")
314  << "OpFastScintillation: using semi-analytic model for number of hits";
315 
316  // LAr absorption length in cm
317  std::map<double, double> abs_length_spectrum =
318  lar::providerFrom<detinfo::LArPropertiesService>()->AbsLengthSpectrum();
319  std::vector<double> x_v, y_v;
320  for (auto elem : abs_length_spectrum) {
321  x_v.push_back(elem.first);
322  y_v.push_back(elem.second);
323  }
324  fL_abs_vuv =
325  std::round(interpolate(x_v, y_v, 9.7, false)); // 9.7 eV: peak of VUV emission spectrum
326 
327  // Load Gaisser-Hillas corrections for VUV semi-analytic hits
328  std::cout << "Loading the GH corrections" << std::endl;
331  if (!fIsFlatPDCorr && !fIsDomePDCorr) {
332  throw cet::exception("OpFastScintillation")
333  << "Both isFlatPDCorr and isDomePDCorr parameters are false, at least one type of "
334  "parameterisation is required for the semi-analytic light simulation."
335  << "\n";
336  }
337  if (fIsFlatPDCorr) {
339  }
340  if (fIsDomePDCorr) {
342  }
343  // cathode center coordinates required for corrections
345  fcathode_centre.SetY(fActiveVolumes[0].CenterY());
346  fcathode_centre.SetZ(
347  fActiveVolumes[0].CenterZ()); // to get full cathode dimension rather than just single tpc
348 
349  if (fPVS->StoreReflected()) {
350  fStoreReflected = true;
351  // Load corrections for VIS semi-anlytic hits
352  std::cout << "Loading visible light corrections" << std::endl;
354  if (fIsFlatPDCorr) {
356  }
357  if (fIsDomePDCorr) {
359  }
360 
361  // cathode dimensions
362  fcathode_ydimension = fActiveVolumes[0].SizeY();
363  fcathode_zdimension = fActiveVolumes[0].SizeZ();
364 
365  // set cathode plane struct for solid angle function
369  }
370  else
371  fStoreReflected = false;
372  }
373  }
374  tpbemission = lar::providerFrom<detinfo::LArPropertiesService>()->TpbEm();
375  std::vector<double> parent;
376  parent.reserve(tpbemission.size());
377  for (auto iter = tpbemission.begin(); iter != tpbemission.end(); ++iter) {
378  parent.push_back(iter->second);
379  }
380  fTPBEm = std::make_unique<CLHEP::RandGeneral>(parent.data(), parent.size());
381  }
void LoadTimingsForVISPar(std::vector< double > &distances, std::vector< double > &radial_distances, std::vector< std::vector< std::vector< double >>> &cut_off, std::vector< std::vector< std::vector< double >>> &tau, double &vis_vmean, double &angle_bin_timing_vis) const
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
Point_t GetCathodeCenter() const
Definition: TPCGeo.h:254
std::vector< std::vector< std::vector< double > > > fvispars_dome
OpDetGeo const & OpDetGeoFromOpDet(unsigned int OpDet) const
Returns the geo::OpDetGeo object for the given detector number.
std::vector< geo::Point_t > fOpDetCenter
void LoadTimingsForVUVPar(std::vector< std::vector< double >>(&v)[7], double &step_size, double &max_d, double &min_d, double &vuv_vgroup_mean, double &vuv_vgroup_max, double &inflexion_point_distance, double &angle_bin_timing_vuv) const
std::vector< double > fOpDetHeight
static std::vector< geo::BoxBoundedGeo > extractActiveVolumes(geo::GeometryCore const &geom)
bool isBar() const
Returns whether the detector shape is a bar (TGeoBBox).
Definition: OpDetGeo.h:180
bool const fOnlyActiveVolume
Whether photon propagation is performed only from active volumes.
std::map< double, double > tpbemission
std::vector< std::vector< std::vector< double > > > fvispars_flat
constexpr auto abs(T v)
Returns the absolute value of the argument.
void LoadVisParsFlat(std::vector< double > &vis_distances_x_flat, std::vector< double > &vis_distances_r_flat, std::vector< std::vector< std::vector< double >>> &vispars_flat) const
std::vector< double > fvis_distances_r_flat
std::vector< double > fdistances_refl
std::vector< std::vector< TF1 > > VUV_timing
std::vector< std::vector< double > > fparameters[7]
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
Definition: GeometryCore.h:430
void LoadGHDome(std::vector< std::vector< double >> &GHvuvpars_dome, std::vector< double > &border_corr_angulo_dome, std::vector< std::vector< double >> &border_corr_dome) const
std::vector< std::vector< double > > fGHvuvpars_flat
std::vector< std::vector< double > > VUV_min
std::vector< std::vector< double > > fGHvuvpars_dome
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:65
void LoadVUVSemiAnalyticProperties(bool &isFlatPDCorr, bool &isDomePDCorr, double &delta_angulo_vuv, double &radius) const
TPCGeo const & TPC(TPCID const &tpcid=tpc_zero) const
Returns the specified TPC.
Definition: GeometryCore.h:722
std::vector< double > fborder_corr_angulo_dome
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
bool const bPropagate
Whether propagation of photons is enabled.
std::vector< std::vector< double > > fborder_corr_dome
std::vector< std::vector< double > > fborder_corr_flat
std::vector< double > fvis_distances_x_flat
void LoadGHFlat(std::vector< std::vector< double >> &GHvuvpars_flat, std::vector< double > &border_corr_angulo_flat, std::vector< std::vector< double >> &border_corr_flat) const
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:295
bool usesSemiAnalyticModel() const
Returns whether the semi-analytic visibility parametrization is being used.
void LoadVisParsDome(std::vector< double > &vis_distances_x_dome, std::vector< double > &vis_distances_r_dome, std::vector< std::vector< std::vector< double >>> &vispars_dome) const
std::vector< double > fborder_corr_angulo_flat
std::vector< double > fOpDetLength
std::unique_ptr< CLHEP::RandGeneral > fTPBEm
std::vector< geo::BoxBoundedGeo > const fActiveVolumes
std::vector< std::vector< std::vector< double > > > ftau_pars
double Length() const
Definition: OpDetGeo.h:78
Description of geometry of one entire detector.
Definition: GeometryCore.h:119
std::vector< double > fradial_distances_refl
geo::Point_t const & GetCenter() const
Definition: OpDetGeo.h:72
std::vector< double > fvis_distances_r_dome
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:180
void LoadVisSemiAnalyticProperties(double &delta_angulo_vis, double &radius) const
std::vector< std::vector< std::vector< double > > > fcut_off_pars
bool const fUseNhitsModel
Whether the semi-analytic model is being used for photon visibility.
std::vector< double > fvis_distances_x_dome
double interpolate(const std::vector< double > &xData, const std::vector< double > &yData, double x, bool extrapolate, size_t i=0) const
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
phot::PhotonVisibilityService const *const fPVS
Photon visibility service instance.
std::vector< std::vector< double > > VUV_max
MaybeLogger_< ELseverityLevel::ELsev_success, true > LogTrace
virtual bool ScintByParticleType() const =0
double Height() const
Definition: OpDetGeo.h:80
TGeoShape const * Shape() const
Returns the geometry object as TGeoShape.
Definition: OpDetGeo.h:139
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
larg4::OpFastScintillation::~OpFastScintillation ( )

Definition at line 386 of file OpFastScintillation.cxx.

References theFastIntegralTable, and theSlowIntegralTable.

387  {
388  if (theFastIntegralTable) theFastIntegralTable->clearAndDestroy();
389  if (theSlowIntegralTable) theSlowIntegralTable->clearAndDestroy();
390  }
std::unique_ptr< G4PhysicsTable > theSlowIntegralTable
std::unique_ptr< G4PhysicsTable > theFastIntegralTable

Member Function Documentation

void larg4::OpFastScintillation::AddSaturation ( G4EmSaturation *  sat)
inline

Definition at line 215 of file OpFastScintillation.hh.

215 { emSaturation = sat; }
G4VParticleChange * larg4::OpFastScintillation::AtRestDoIt ( const G4Track &  aTrack,
const G4Step &  aStep 
)
virtual

Definition at line 399 of file OpFastScintillation.cxx.

References PostStepDoIt().

402  {
403  return OpFastScintillation::PostStepDoIt(aTrack, aStep);
404  }
virtual G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
void larg4::OpFastScintillation::average_position ( G4Step const &  aStep,
double *  xzyPos 
) const
private

Definition at line 1080 of file OpFastScintillation.cxx.

Referenced by RecordPhotonsProduced().

1081  {
1082  CLHEP::Hep3Vector prePoint = (aStep.GetPreStepPoint())->GetPosition();
1083  CLHEP::Hep3Vector postPoint = (aStep.GetPostStepPoint())->GetPosition();
1084  xyzPos[0] = (((prePoint.getX() + postPoint.getX()) / 2.0) / CLHEP::cm);
1085  xyzPos[1] = (((prePoint.getY() + postPoint.getY()) / 2.0) / CLHEP::cm);
1086  xyzPos[2] = (((prePoint.getZ() + postPoint.getZ()) / 2.0) / CLHEP::cm);
1087  }
G4double larg4::OpFastScintillation::bi_exp ( const G4double  t,
const G4double  tau1,
const G4double  tau2 
) const
private

Definition at line 1833 of file OpFastScintillation.cxx.

Referenced by sample_time().

1836  { // TODO: what's up with this? ... / tau2 / tau2 ...
1837  return std::exp(-1.0 * t / tau2) * (1 - std::exp(-1.0 * t / tau1)) / tau2 / tau2 *
1838  (tau1 + tau2);
1839  }
void larg4::OpFastScintillation::BuildThePhysicsTable ( )
protected

Definition at line 853 of file OpFastScintillation.cxx.

References theFastIntegralTable, and theSlowIntegralTable.

Referenced by OpFastScintillation().

854  {
856 
857  const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
858  G4int numOfMaterials = G4Material::GetNumberOfMaterials();
859 
860  // create new physics table
862  theFastIntegralTable = std::make_unique<G4PhysicsTable>(numOfMaterials);
864  theSlowIntegralTable = std::make_unique<G4PhysicsTable>(numOfMaterials);
865 
866  // loop for materials
867  for (G4int i = 0; i < numOfMaterials; i++) {
868  G4PhysicsOrderedFreeVector* aPhysicsOrderedFreeVector = new G4PhysicsOrderedFreeVector();
869  G4PhysicsOrderedFreeVector* bPhysicsOrderedFreeVector = new G4PhysicsOrderedFreeVector();
870 
871  // Retrieve vector of scintillation wavelength intensity for
872  // the material from the material's optical properties table.
873  G4Material* aMaterial = (*theMaterialTable)[i];
874 
875  G4MaterialPropertiesTable* aMaterialPropertiesTable = aMaterial->GetMaterialPropertiesTable();
876 
877  if (aMaterialPropertiesTable) {
878 
879  G4MaterialPropertyVector* theFastLightVector =
880  aMaterialPropertiesTable->GetProperty("FASTCOMPONENT");
881 
882  if (theFastLightVector) {
883  // Retrieve the first intensity point in vector
884  // of (photon energy, intensity) pairs
885  G4double currentIN = (*theFastLightVector)[0];
886  if (currentIN >= 0.0) {
887  // Create first (photon energy, Scintillation
888  // Integral pair
889  G4double currentPM = theFastLightVector->Energy(0);
890  G4double currentCII = 0.0;
891 
892  aPhysicsOrderedFreeVector->InsertValues(currentPM, currentCII);
893 
894  // Set previous values to current ones prior to loop
895  G4double prevPM = currentPM;
896  G4double prevCII = currentCII;
897  G4double prevIN = currentIN;
898 
899  // loop over all (photon energy, intensity)
900  // pairs stored for this material
901  for (size_t i = 1; i < theFastLightVector->GetVectorLength(); i++) {
902  currentPM = theFastLightVector->Energy(i);
903  currentIN = (*theFastLightVector)[i];
904 
905  currentCII = 0.5 * (prevIN + currentIN);
906 
907  currentCII = prevCII + (currentPM - prevPM) * currentCII;
908 
909  aPhysicsOrderedFreeVector->InsertValues(currentPM, currentCII);
910 
911  prevPM = currentPM;
912  prevCII = currentCII;
913  prevIN = currentIN;
914  }
915  }
916  }
917 
918  G4MaterialPropertyVector* theSlowLightVector =
919  aMaterialPropertiesTable->GetProperty("SLOWCOMPONENT");
920  if (theSlowLightVector) {
921  // Retrieve the first intensity point in vector
922  // of (photon energy, intensity) pairs
923  G4double currentIN = (*theSlowLightVector)[0];
924  if (currentIN >= 0.0) {
925  // Create first (photon energy, Scintillation
926  // Integral pair
927  G4double currentPM = theSlowLightVector->Energy(0);
928  G4double currentCII = 0.0;
929 
930  bPhysicsOrderedFreeVector->InsertValues(currentPM, currentCII);
931 
932  // Set previous values to current ones prior to loop
933  G4double prevPM = currentPM;
934  G4double prevCII = currentCII;
935  G4double prevIN = currentIN;
936 
937  // loop over all (photon energy, intensity)
938  // pairs stored for this material
939  for (size_t i = 1; i < theSlowLightVector->GetVectorLength(); i++) {
940  currentPM = theSlowLightVector->Energy(i);
941  currentIN = (*theSlowLightVector)[i];
942 
943  currentCII = 0.5 * (prevIN + currentIN);
944 
945  currentCII = prevCII + (currentPM - prevPM) * currentCII;
946 
947  bPhysicsOrderedFreeVector->InsertValues(currentPM, currentCII);
948 
949  prevPM = currentPM;
950  prevCII = currentCII;
951  prevIN = currentIN;
952  }
953  }
954  }
955  }
956  // The scintillation integral(s) for a given material
957  // will be inserted in the table(s) according to the
958  // position of the material in the material table.
959  theFastIntegralTable->insertAt(i, aPhysicsOrderedFreeVector);
960  theSlowIntegralTable->insertAt(i, bPhysicsOrderedFreeVector);
961  }
962  }
std::unique_ptr< G4PhysicsTable > theSlowIntegralTable
std::unique_ptr< G4PhysicsTable > theFastIntegralTable
void larg4::OpFastScintillation::detectedDirectHits ( std::map< size_t, int > &  DetectedNum,
const double  Num,
geo::Point_t const &  ScintPoint 
) const

Definition at line 1478 of file OpFastScintillation.cxx.

References util::counter(), fOpDetCenter, fOpDetHeight, fOpDetLength, fOpDetType, fPVS, isOpDetInSameTPC(), phot::PhotonVisibilityService::NOpChannels(), and VUVHits().

Referenced by RecordPhotonsProduced().

1481  {
1482  for (size_t const OpDet : util::counter(fPVS->NOpChannels())) {
1483  if (!isOpDetInSameTPC(ScintPoint, fOpDetCenter.at(OpDet))) continue;
1484 
1485  // set detector struct for solid angle function
1486  const OpFastScintillation::OpticalDetector op{fOpDetHeight.at(OpDet),
1487  fOpDetLength.at(OpDet),
1488  fOpDetCenter.at(OpDet),
1489  fOpDetType.at(OpDet)};
1490  const int DetThis = VUVHits(Num, ScintPoint, op);
1491  if (DetThis > 0) {
1492  DetectedNum[OpDet] = DetThis;
1493  // mf::LogInfo("OpFastScintillation") << "FastScint: " <<
1494  // // it->second<<" " << Num << " " << DetThisPMT;
1495  //det_photon_ctr += DetThisPMT; // CASE-DEBUG DO NOT REMOVE THIS COMMENT
1496  }
1497  }
1498  }
std::vector< geo::Point_t > fOpDetCenter
std::vector< double > fOpDetHeight
bool isOpDetInSameTPC(geo::Point_t const &ScintPoint, geo::Point_t const &OpDetPoint) const
int VUVHits(const double Nphotons_created, geo::Point_t const &ScintPoint, OpticalDetector const &opDet) const
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:295
std::vector< double > fOpDetLength
phot::PhotonVisibilityService const *const fPVS
Photon visibility service instance.
void larg4::OpFastScintillation::detectedReflecHits ( std::map< size_t, int > &  ReflDetectedNum,
const double  Num,
geo::Point_t const &  ScintPoint 
) const

Definition at line 1500 of file OpFastScintillation.cxx.

References util::abs(), util::counter(), fborder_corr_angulo_flat, fborder_corr_flat, fcathode_centre, fcathode_plane, fGHvuvpars_flat, fIsFlatPDCorr, fL_abs_vuv, fOpDetCenter, fOpDetHeight, fOpDetLength, fOpDetType, fplane_depth, fPVS, Gaisser_Hillas(), interpolate(), isOpDetInSameTPC(), phot::PhotonVisibilityService::NOpChannels(), util::pi(), r, Rectangle_SolidAngle(), and VISHits().

Referenced by RecordPhotonsProduced().

1503  {
1504  // 1). calculate total number of hits of VUV photons on
1505  // reflective foils via solid angle + Gaisser-Hillas
1506  // corrections:
1507 
1508  // set plane_depth for correct TPC:
1509  double plane_depth;
1510  if (ScintPoint.X() < 0.) { plane_depth = -fplane_depth; }
1511  else {
1512  plane_depth = fplane_depth;
1513  }
1514 
1515  // get scintpoint coords relative to centre of cathode plane
1516  std::array<double, 3> ScintPoint_relative = {std::abs(ScintPoint.X() - plane_depth),
1517  std::abs(ScintPoint.Y() - fcathode_centre.Y()),
1518  std::abs(ScintPoint.Z() - fcathode_centre.Z())};
1519  // calculate solid angle of cathode from the scintillation point
1520  double solid_angle_cathode = Rectangle_SolidAngle(fcathode_plane, ScintPoint_relative);
1521 
1522  // calculate distance and angle between ScintPoint and hotspot
1523  // vast majority of hits in hotspot region directly infront of scintpoint,
1524  // therefore consider attenuation for this distance and on axis GH instead of for the centre coordinate
1525  double distance_cathode = std::abs(plane_depth - ScintPoint.X());
1526  // calculate hits on cathode plane via geometric acceptance
1527  double cathode_hits_geo = std::exp(-1. * distance_cathode / fL_abs_vuv) *
1528  (solid_angle_cathode / (4. * CLHEP::pi)) * Num;
1529  // determine Gaisser-Hillas correction including border effects
1530  // use flat correction
1531  double r = std::sqrt(std::pow(ScintPoint.Y() - fcathode_centre.Y(), 2) +
1532  std::pow(ScintPoint.Z() - fcathode_centre.Z(), 2));
1533  double pars_ini[4] = {0, 0, 0, 0};
1534  double s1 = 0;
1535  double s2 = 0;
1536  double s3 = 0;
1537  if (fIsFlatPDCorr) {
1538  pars_ini[0] = fGHvuvpars_flat[0][0];
1539  pars_ini[1] = fGHvuvpars_flat[1][0];
1540  pars_ini[2] = fGHvuvpars_flat[2][0];
1541  pars_ini[3] = fGHvuvpars_flat[3][0];
1545  }
1546  else
1547  std::cout
1548  << "Error: flat optical detector VUV correction required for reflected semi-analytic hits."
1549  << std::endl;
1550 
1551  // add border correction
1552  pars_ini[0] = pars_ini[0] + s1 * r;
1553  pars_ini[1] = pars_ini[1] + s2 * r;
1554  pars_ini[2] = pars_ini[2] + s3 * r;
1555  pars_ini[3] = pars_ini[3];
1556 
1557  // calculate corrected number of hits
1558  double GH_correction = Gaisser_Hillas(distance_cathode, pars_ini);
1559  const double cathode_hits_rec = GH_correction * cathode_hits_geo;
1560 
1561  // detemine hits on each PD
1562  const std::array<double, 3> hotspot = {plane_depth, ScintPoint.Y(), ScintPoint.Z()};
1563  for (size_t const OpDet : util::counter(fPVS->NOpChannels())) {
1564  if (!isOpDetInSameTPC(ScintPoint, fOpDetCenter.at(OpDet))) continue;
1565 
1566  // set detector struct for solid angle function
1567  const OpFastScintillation::OpticalDetector op{fOpDetHeight.at(OpDet),
1568  fOpDetLength.at(OpDet),
1569  fOpDetCenter.at(OpDet),
1570  fOpDetType.at(OpDet)};
1571 
1572  int const ReflDetThis = VISHits(ScintPoint, op, cathode_hits_rec, hotspot);
1573  if (ReflDetThis > 0) { ReflDetectedNum[OpDet] = ReflDetThis; }
1574  }
1575  }
TRandom r
Definition: spectrum.C:23
std::vector< geo::Point_t > fOpDetCenter
G4double Gaisser_Hillas(const double x, const double *par) const
std::vector< double > fOpDetHeight
int VISHits(geo::Point_t const &ScintPoint, OpticalDetector const &opDet, const double cathode_hits_rec, const std::array< double, 3 > hotspot) const
constexpr auto abs(T v)
Returns the absolute value of the argument.
bool isOpDetInSameTPC(geo::Point_t const &ScintPoint, geo::Point_t const &OpDetPoint) const
std::vector< std::vector< double > > fGHvuvpars_flat
std::vector< std::vector< double > > fborder_corr_flat
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:295
std::vector< double > fborder_corr_angulo_flat
std::vector< double > fOpDetLength
double Rectangle_SolidAngle(const double a, const double b, const double d) const
double interpolate(const std::vector< double > &xData, const std::vector< double > &yData, double x, bool extrapolate, size_t i=0) const
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
phot::PhotonVisibilityService const *const fPVS
Photon visibility service instance.
double larg4::OpFastScintillation::Disk_SolidAngle ( const double  d,
const double  h,
const double  b 
) const
private

Definition at line 1990 of file OpFastScintillation.cxx.

References d, e, larg4::isApproximatelyEqual(), larg4::isApproximatelyZero(), larg4::isDefinitelyGreaterThan(), larg4::isDefinitelyLessThan(), and util::pi().

Referenced by VISHits(), and VUVHits().

1991  {
1992  if (b <= 0. || d < 0. || h <= 0.) return 0.;
1993  const double leg2 = (b + d) * (b + d);
1994  const double aa = std::sqrt(h * h / (h * h + leg2));
1995  if (isApproximatelyZero(d)) { return 2. * CLHEP::pi * (1. - aa); }
1996  double bb = 2. * std::sqrt(b * d / (h * h + leg2));
1997  double cc = 4. * b * d / leg2;
1998 
1999  if (isDefinitelyGreaterThan(d, b)) {
2000  try {
2001  return 2. * aa *
2002  (std::sqrt(1. - cc) * boost::math::ellint_3(bb, cc, noLDoublePromote()) -
2003  boost::math::ellint_1(bb, noLDoublePromote()));
2004  }
2005  catch (std::domain_error& e) {
2006  if (isApproximatelyEqual(d, b, 1e-9)) {
2007  mf::LogWarning("OpFastScintillation")
2008  << "Elliptic Integral in Disk_SolidAngle() given parameters outside domain."
2009  << "\nbb: " << bb << "\ncc: " << cc << "\nException message: " << e.what()
2010  << "\nRelax condition and carry on.";
2011  return CLHEP::pi - 2. * aa * boost::math::ellint_1(bb, noLDoublePromote());
2012  }
2013  else {
2014  mf::LogError("OpFastScintillation")
2015  << "Elliptic Integral inside Disk_SolidAngle() given parameters outside domain.\n"
2016  << "\nbb: " << bb << "\ncc: " << cc << "Exception message: " << e.what();
2017  return 0.;
2018  }
2019  }
2020  }
2021  if (isDefinitelyLessThan(d, b)) {
2022  try {
2023  return 2. * CLHEP::pi -
2024  2. * aa *
2025  (boost::math::ellint_1(bb, noLDoublePromote()) +
2026  std::sqrt(1. - cc) * boost::math::ellint_3(bb, cc, noLDoublePromote()));
2027  }
2028  catch (std::domain_error& e) {
2029  if (isApproximatelyEqual(d, b, 1e-9)) {
2030  mf::LogWarning("OpFastScintillation")
2031  << "Elliptic Integral in Disk_SolidAngle() given parameters outside domain."
2032  << "\nbb: " << bb << "\ncc: " << cc << "\nException message: " << e.what()
2033  << "\nRelax condition and carry on.";
2034  return CLHEP::pi - 2. * aa * boost::math::ellint_1(bb, noLDoublePromote());
2035  }
2036  else {
2037  mf::LogError("OpFastScintillation")
2038  << "Elliptic Integral inside Disk_SolidAngle() given parameters outside domain.\n"
2039  << "\nbb: " << bb << "\ncc: " << cc << "Exception message: " << e.what();
2040  return 0.;
2041  }
2042  }
2043  }
2044  if (isApproximatelyEqual(d, b)) {
2045  return CLHEP::pi - 2. * aa * boost::math::ellint_1(bb, noLDoublePromote());
2046  }
2047  return 0.;
2048  }
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
boost::math::policies::policy< boost::math::policies::promote_double< false > > noLDoublePromote
Float_t d
Definition: plot.C:235
static constexpr bool isDefinitelyGreaterThan(TReal a, TReal b, TReal tolerance=std::numeric_limits< TReal >::epsilon())
static constexpr bool isApproximatelyEqual(TReal a, TReal b, TReal tolerance=std::numeric_limits< TReal >::epsilon())
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
static constexpr bool isDefinitelyLessThan(TReal a, TReal b, TReal tolerance=std::numeric_limits< TReal >::epsilon())
Float_t e
Definition: plot.C:35
static constexpr bool isApproximatelyZero(TReal a, TReal tolerance=std::numeric_limits< TReal >::epsilon())
void larg4::OpFastScintillation::DumpPhysicsTable ( ) const
inline

Definition at line 516 of file OpFastScintillation.hh.

517  {
518  if (theFastIntegralTable) {
519  G4int PhysicsTableSize = theFastIntegralTable->entries();
520  G4PhysicsOrderedFreeVector* v;
521  for (G4int i = 0; i < PhysicsTableSize; i++) {
522  v = (G4PhysicsOrderedFreeVector*)(*theFastIntegralTable)[i];
523  v->DumpValues();
524  }
525  }
526  if (theSlowIntegralTable) {
527  G4int PhysicsTableSize = theSlowIntegralTable->entries();
528  G4PhysicsOrderedFreeVector* v;
529  for (G4int i = 0; i < PhysicsTableSize; i++) {
530  v = (G4PhysicsOrderedFreeVector*)(*theSlowIntegralTable)[i];
531  v->DumpValues();
532  }
533  }
534  }
std::unique_ptr< G4PhysicsTable > theSlowIntegralTable
std::unique_ptr< G4PhysicsTable > theFastIntegralTable
std::vector< geo::BoxBoundedGeo > larg4::OpFastScintillation::extractActiveVolumes ( geo::GeometryCore const &  geom)
staticprivate

Definition at line 2149 of file OpFastScintillation.cxx.

References geo::BoxBoundedGeo::ExtendToInclude(), geo::GeometryCore::Iterate(), and geo::GeometryCore::Ncryostats().

Referenced by OpFastScintillation().

2151  {
2152  std::vector<geo::BoxBoundedGeo> activeVolumes;
2153  activeVolumes.reserve(geom.Ncryostats());
2154 
2155  for (geo::CryostatGeo const& cryo : geom.Iterate<geo::CryostatGeo>()) {
2156 
2157  // can't use it default-constructed since it would always include origin
2158  geo::BoxBoundedGeo box{cryo.TPC(0).ActiveBoundingBox()};
2159 
2160  for (geo::TPCGeo const& TPC : cryo.IterateTPCs())
2161  box.ExtendToInclude(TPC.ActiveBoundingBox());
2162 
2163  activeVolumes.push_back(std::move(box));
2164 
2165  } // for cryostats
2166 
2167  return activeVolumes;
2168  } // OpFastScintillation::extractActiveVolumes()
Geometry information for a single TPC.
Definition: TPCGeo.h:36
Geometry information for a single cryostat.
Definition: CryostatGeo.h:43
A base class aware of world box coordinatesAn object describing a simple shape can inherit from this ...
Definition: BoxBoundedGeo.h:33
void ExtendToInclude(Coord_t x, Coord_t y, Coord_t z)
Extends the current box to also include the specified point.
G4double larg4::OpFastScintillation::Gaisser_Hillas ( const double  x,
const double *  par 
) const
private

Definition at line 1841 of file OpFastScintillation.cxx.

Referenced by detectedReflecHits(), and VUVHits().

1842  {
1843  double X_mu_0 = par[3];
1844  double Normalization = par[0];
1845  double Diff = par[1] - X_mu_0;
1846  double Term = std::pow((x - X_mu_0) / Diff, Diff / par[2]);
1847  double Exponential = std::exp((par[1] - x) / par[2]);
1848  return (Normalization * Term * Exponential);
1849  }
Float_t x
Definition: compare.C:6
void larg4::OpFastScintillation::generateParam ( const size_t  index,
const size_t  angle_bin 
)

Definition at line 1229 of file OpFastScintillation.cxx.

References finflexion_point_distance, larg4::finter_d(), fmin_d, fparameters, fstep_size, fvuv_vgroup_max, fvuv_vgroup_mean, interpolate(), interpolate3(), larg4::model_close(), larg4::model_far(), VUV_max, VUV_min, and VUV_timing.

Referenced by getVUVTimes().

1230  {
1231  // get distance
1232  double distance_in_cm = (index * fstep_size) + fmin_d;
1233 
1234  // time range
1235  const double signal_t_range = 5000.; // TODO: unhardcode
1236 
1237  // parameterisation TF1
1238  TF1 fVUVTiming;
1239 
1240  // For very short distances the time correction is just a shift
1241  double t_direct_mean = distance_in_cm / fvuv_vgroup_mean;
1242  double t_direct_min = distance_in_cm / fvuv_vgroup_max;
1243 
1244  // Defining the model function(s) describing the photon transportation timing vs distance
1245  // Getting the landau parameters from the time parametrization
1246  std::array<double, 3> pars_landau;
1247  interpolate3(pars_landau,
1248  fparameters[0][0],
1249  fparameters[2][angle_bin],
1250  fparameters[3][angle_bin],
1251  fparameters[1][angle_bin],
1252  distance_in_cm,
1253  true);
1254  // Deciding which time model to use (depends on the distance)
1255  // defining useful times for the VUV arrival time shapes
1256  if (distance_in_cm >= finflexion_point_distance) {
1257  double pars_far[4] = {t_direct_min, pars_landau[0], pars_landau[1], pars_landau[2]};
1258  // Set model: Landau
1259  fVUVTiming = TF1("fVUVTiming", model_far, 0, signal_t_range, 4);
1260  fVUVTiming.SetParameters(pars_far);
1261  }
1262  else {
1263  // Set model: Landau + Exponential
1264  fVUVTiming = TF1("fVUVTiming", model_close, 0, signal_t_range, 7);
1265  // Exponential parameters
1266  double pars_expo[2];
1267  // Getting the exponential parameters from the time parametrization
1268  pars_expo[1] =
1269  interpolate(fparameters[4][0], fparameters[5][angle_bin], distance_in_cm, true);
1270  pars_expo[0] =
1271  interpolate(fparameters[4][0], fparameters[6][angle_bin], distance_in_cm, true);
1272  pars_expo[0] *= pars_landau[2];
1273  pars_expo[0] = std::log(pars_expo[0]);
1274  // this is to find the intersection point between the two functions:
1275  TF1 fint = TF1("fint", finter_d, pars_landau[0], 4 * t_direct_mean, 5);
1276  double parsInt[5] = {
1277  pars_landau[0], pars_landau[1], pars_landau[2], pars_expo[0], pars_expo[1]};
1278  fint.SetParameters(parsInt);
1279  double t_int = fint.GetMinimumX();
1280  double minVal = fint.Eval(t_int);
1281  // the functions must intersect - output warning if they don't
1282  if (minVal > 0.015) {
1283  std::cout << "WARNING: Parametrization of VUV light discontinuous for distance = "
1284  << distance_in_cm << std::endl;
1285  std::cout << "WARNING: This shouldn't be happening " << std::endl;
1286  }
1287  double parsfinal[7] = {t_int,
1288  pars_landau[0],
1289  pars_landau[1],
1290  pars_landau[2],
1291  pars_expo[0],
1292  pars_expo[1],
1293  t_direct_min};
1294  fVUVTiming.SetParameters(parsfinal);
1295  }
1296 
1297  // set the number of points used to sample parameterisation
1298  // for shorter distances, peak is sharper so more sensitive sampling required
1299  int fsampling; // TODO: unhardcode
1300  if (distance_in_cm < 50) { fsampling = 10000; }
1301  else if (distance_in_cm < 100) {
1302  fsampling = 5000;
1303  }
1304  else {
1305  fsampling = 1000;
1306  }
1307  fVUVTiming.SetNpx(fsampling);
1308 
1309  // calculate max and min distance relevant to sample parameterisation
1310  // max
1311  const size_t nq_max = 1;
1312  double xq_max[nq_max];
1313  double yq_max[nq_max];
1314  xq_max[0] = 0.995; // include 99.5%
1315  fVUVTiming.GetQuantiles(nq_max, yq_max, xq_max);
1316  double max = yq_max[0];
1317  // min
1318  double min = t_direct_min;
1319 
1320  // store TF1 and min/max, this allows identical TF1 to be used every time sampling
1321  // the first call of GetRandom generates the timing sampling and stores it in the TF1 object, this is the slow part
1322  // all subsequent calls check if it has been generated previously and are ~100+ times quicker
1323  VUV_timing[angle_bin][index] = fVUVTiming;
1324  VUV_max[angle_bin][index] = max;
1325  VUV_min[angle_bin][index] = min;
1326  }
double finter_d(double *x, double *par)
double model_far(double *x, double *par)
std::vector< std::vector< TF1 > > VUV_timing
std::vector< std::vector< double > > fparameters[7]
double model_close(double *x, double *par)
std::vector< std::vector< double > > VUV_min
void interpolate3(std::array< double, 3 > &inter, const std::vector< double > &xData, const std::vector< double > &yData1, const std::vector< double > &yData2, const std::vector< double > &yData3, double x, bool extrapolate) const
double interpolate(const std::vector< double > &xData, const std::vector< double > &yData, double x, bool extrapolate, size_t i=0) const
std::vector< std::vector< double > > VUV_max
G4PhysicsTable * larg4::OpFastScintillation::GetFastIntegralTable ( ) const
inline

Definition at line 511 of file OpFastScintillation.hh.

512  {
513  return theFastIntegralTable.get();
514  }
std::unique_ptr< G4PhysicsTable > theFastIntegralTable
G4bool larg4::OpFastScintillation::GetFiniteRiseTime ( ) const
inline

Definition at line 481 of file OpFastScintillation.hh.

482  {
483  return fFiniteRiseTime;
484  }
G4double larg4::OpFastScintillation::GetMeanFreePath ( const G4Track &  aTrack,
G4double  ,
G4ForceCondition *  condition 
)

Definition at line 978 of file OpFastScintillation.cxx.

981  {
982  *condition = StronglyForced;
983  return DBL_MAX;
984  }
G4double larg4::OpFastScintillation::GetMeanLifeTime ( const G4Track &  aTrack,
G4ForceCondition *  condition 
)

Definition at line 986 of file OpFastScintillation.cxx.

987  {
988  *condition = Forced;
989  return DBL_MAX;
990  }
G4EmSaturation* larg4::OpFastScintillation::GetSaturation ( ) const
inline

Definition at line 221 of file OpFastScintillation.hh.

221 { return emSaturation; }
G4bool larg4::OpFastScintillation::GetScintillationByParticleType ( ) const
inline

Definition at line 228 of file OpFastScintillation.hh.

G4double larg4::OpFastScintillation::GetScintillationExcitationRatio ( ) const
inline

Definition at line 501 of file OpFastScintillation.hh.

502  {
503  return ExcitationRatio;
504  }
G4double larg4::OpFastScintillation::GetScintillationYieldFactor ( ) const
inline

Definition at line 491 of file OpFastScintillation.hh.

492  {
493  return YieldFactor;
494  }
G4PhysicsTable * larg4::OpFastScintillation::GetSlowIntegralTable ( ) const
inline

Definition at line 506 of file OpFastScintillation.hh.

507  {
508  return theSlowIntegralTable.get();
509  }
std::unique_ptr< G4PhysicsTable > theSlowIntegralTable
G4bool larg4::OpFastScintillation::GetTrackSecondariesFirst ( ) const
inline

Definition at line 476 of file OpFastScintillation.hh.

477  {
478  return fTrackSecondariesFirst;
479  }
void larg4::OpFastScintillation::getVISTimes ( std::vector< double > &  arrivalTimes,
const TVector3 &  ScintPoint,
const TVector3 &  OpDetPoint 
)

Definition at line 1354 of file OpFastScintillation.cxx.

References util::abs(), util::counter(), fangle_bin_timing_vis, larg4::fast_acos(), fcathode_centre, fcut_off_pars, fdistances_refl, fmin_d, fplane_depth, fradial_distances_refl, fstep_size, ftau_pars, fvis_vmean, fvuv_vgroup_max, getVUVTimes(), interpolate(), util::pi(), r, util::size(), VUV_min, and x.

Referenced by propagationTime().

1357  {
1358  // *************************************************************************************************
1359  // Calculation of earliest arrival times and corresponding unsmeared distribution
1360  // *************************************************************************************************
1361 
1362  // set plane_depth for correct TPC:
1363  double plane_depth;
1364  if (ScintPoint[0] < 0) { plane_depth = -fplane_depth; }
1365  else {
1366  plane_depth = fplane_depth;
1367  }
1368 
1369  // calculate point of reflection for shortest path
1370  TVector3 bounce_point(plane_depth, ScintPoint[1], ScintPoint[2]);
1371 
1372  // calculate distance travelled by VUV light and by vis light
1373  double VUVdist = (bounce_point - ScintPoint).Mag();
1374  double Visdist = (OpDetPoint - bounce_point).Mag();
1375 
1376  // calculate times taken by VUV part of path
1377  int angle_bin_vuv = 0; // on-axis by definition
1378  getVUVTimes(arrivalTimes, VUVdist, angle_bin_vuv);
1379 
1380  // add visible direct path transport time
1381  for (size_t i = 0; i < arrivalTimes.size(); ++i) {
1382  arrivalTimes[i] += Visdist / fvis_vmean;
1383  }
1384 
1385  // *************************************************************************************************
1386  // Smearing of arrival time distribution
1387  // *************************************************************************************************
1388  // calculate fastest time possible
1389  // vis part
1390  double vis_time = Visdist / fvis_vmean;
1391  // vuv part
1392  double vuv_time;
1393  if (VUVdist < fmin_d) { vuv_time = VUVdist / fvuv_vgroup_max; }
1394  else {
1395  // find index of required parameterisation
1396  const size_t index = std::round((VUVdist - fmin_d) / fstep_size);
1397  // find shortest time
1398  vuv_time = VUV_min[angle_bin_vuv][index];
1399  }
1400  // sum
1401  double fastest_time = vis_time + vuv_time;
1402 
1403  // calculate angle theta between bound_point and optical detector
1404  double cosine_theta = std::abs(OpDetPoint[0] - bounce_point[0]) / Visdist;
1405  double theta = fast_acos(cosine_theta) * 180. / CLHEP::pi;
1406 
1407  // determine smearing parameters using interpolation of generated points:
1408  // 1). tau = exponential smearing factor, varies with distance and angle
1409  // 2). cutoff = largest smeared time allowed, preventing excessively large
1410  // times caused by exponential distance to cathode
1411  double distance_cathode_plane = std::abs(plane_depth - ScintPoint[0]);
1412  // angular bin
1413  size_t theta_bin = theta / fangle_bin_timing_vis;
1414  // radial distance from centre of TPC (y,z plane)
1415  double r = std::sqrt(std::pow(ScintPoint.Y() - fcathode_centre.Z(), 2) +
1416  std::pow(ScintPoint.Y() - fcathode_centre.Z(), 2));
1417 
1418  // cut-off and tau
1419  // cut-off
1420  // interpolate in d_c for each r bin
1421  std::vector<double> interp_vals(fcut_off_pars[theta_bin].size(), 0.0);
1422  for (size_t i = 0; i < fcut_off_pars[theta_bin].size(); i++) {
1423  interp_vals[i] =
1424  interpolate(fdistances_refl, fcut_off_pars[theta_bin][i], distance_cathode_plane, true);
1425  }
1426  // interpolate in r
1427  double cutoff = interpolate(fradial_distances_refl, interp_vals, r, true);
1428 
1429  // tau
1430  // interpolate in x for each r bin
1431  std::vector<double> interp_vals_tau(ftau_pars[theta_bin].size(), 0.0);
1432  for (size_t i = 0; i < ftau_pars[theta_bin].size(); i++) {
1433  interp_vals_tau[i] =
1434  interpolate(fdistances_refl, ftau_pars[theta_bin][i], distance_cathode_plane, true);
1435  }
1436  // interpolate in r
1437  double tau = interpolate(fradial_distances_refl, interp_vals_tau, r, true);
1438 
1439  if (tau < 0) { tau = 0; } // failsafe if tau extrapolate goes wrong
1440 
1441  // apply smearing:
1442  for (size_t i = 0; i < arrivalTimes.size(); ++i) {
1443  double arrival_time_smeared;
1444  // if time is already greater than cutoff, do not apply smearing
1445  if (arrivalTimes[i] >= cutoff) { continue; }
1446  // otherwise smear
1447  else {
1448  unsigned int counter = 0;
1449  // loop until time generated is within cutoff limit
1450  // most are within single attempt, very few take more than two
1451  do {
1452  // don't attempt smearings too many times
1453  if (counter >= 10) { // TODO: unhardcode
1454  arrival_time_smeared = arrivalTimes[i]; // don't smear
1455  break;
1456  }
1457  else {
1458  // generate random number in appropriate range
1459  double x = gRandom->Uniform(0.5, 1.0); // TODO: unhardcode
1460  // apply the exponential smearing
1461  arrival_time_smeared =
1462  arrivalTimes[i] + (arrivalTimes[i] - fastest_time) * (std::pow(x, -tau) - 1);
1463  }
1464  counter++;
1465  } while (arrival_time_smeared > cutoff);
1466  }
1467  arrivalTimes[i] = arrival_time_smeared;
1468  }
1469  }
Float_t x
Definition: compare.C:6
TRandom r
Definition: spectrum.C:23
constexpr auto abs(T v)
Returns the absolute value of the argument.
std::vector< double > fdistances_refl
std::vector< std::vector< double > > VUV_min
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:295
std::vector< std::vector< std::vector< double > > > ftau_pars
std::vector< double > fradial_distances_refl
std::vector< std::vector< std::vector< double > > > fcut_off_pars
void getVUVTimes(std::vector< double > &arrivalTimes, const double distance_in_cm, const size_t angle_bin)
double interpolate(const std::vector< double > &xData, const std::vector< double > &yData, double x, bool extrapolate, size_t i=0) const
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
double fast_acos(double x)
void larg4::OpFastScintillation::getVUVTimes ( std::vector< double > &  arrivalTimes,
const double  distance_in_cm,
const size_t  angle_bin 
)

Definition at line 1329 of file OpFastScintillation.cxx.

References fmin_d, fstep_size, fvuv_vgroup_mean, generateParam(), VUV_max, VUV_min, and VUV_timing.

Referenced by getVISTimes(), and propagationTime().

1332  {
1333  if (distance < fmin_d) {
1334  // times are fixed shift i.e. direct path only
1335  double t_prop_correction = distance / fvuv_vgroup_mean;
1336  for (size_t i = 0; i < arrivalTimes.size(); ++i) {
1337  arrivalTimes[i] = t_prop_correction;
1338  }
1339  }
1340  else { // distance >= fmin_d
1341  // determine nearest parameterisation in discretisation
1342  int index = std::round((distance - fmin_d) / fstep_size);
1343  // check whether required parameterisation has been generated, generating if not
1344  if (VUV_timing[angle_bin][index].GetNdim() == 0) { generateParam(index, angle_bin); }
1345  // randomly sample parameterisation for each photon
1346  for (size_t i = 0; i < arrivalTimes.size(); ++i) {
1347  arrivalTimes[i] = VUV_timing[angle_bin][index].GetRandom(VUV_min[angle_bin][index],
1348  VUV_max[angle_bin][index]);
1349  }
1350  }
1351  }
std::vector< std::vector< TF1 > > VUV_timing
std::vector< std::vector< double > > VUV_min
void generateParam(const size_t index, const size_t angle_bin)
std::vector< std::vector< double > > VUV_max
double larg4::OpFastScintillation::interpolate ( const std::vector< double > &  xData,
const std::vector< double > &  yData,
double  x,
bool  extrapolate,
size_t  i = 0 
) const
private

Definition at line 1911 of file OpFastScintillation.cxx.

References util::size().

Referenced by detectedReflecHits(), generateParam(), getVISTimes(), OpFastScintillation(), VISHits(), and VUVHits().

1916  {
1917  if (i == 0) {
1918  size_t size = xData.size();
1919  if (x >= xData[size - 2]) { // special case: beyond right end
1920  i = size - 2;
1921  }
1922  else {
1923  while (x > xData[i + 1])
1924  i++;
1925  }
1926  }
1927  double xL = xData[i];
1928  double xR = xData[i + 1];
1929  double yL = yData[i];
1930  double yR = yData[i + 1]; // points on either side (unless beyond ends)
1931  if (!extrapolate) { // if beyond ends of array and not extrapolating
1932  if (x < xL) return yL;
1933  if (x > xR) return yL;
1934  }
1935  const double dydx = (yR - yL) / (xR - xL); // gradient
1936  return yL + dydx * (x - xL); // linear interpolation
1937  }
Float_t x
Definition: compare.C:6
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
void larg4::OpFastScintillation::interpolate3 ( std::array< double, 3 > &  inter,
const std::vector< double > &  xData,
const std::vector< double > &  yData1,
const std::vector< double > &  yData2,
const std::vector< double > &  yData3,
double  x,
bool  extrapolate 
) const
private

Definition at line 1939 of file OpFastScintillation.cxx.

References util::size().

Referenced by generateParam().

1946  {
1947  size_t size = xData.size();
1948  size_t i = 0; // find left end of interval for interpolation
1949  if (x >= xData[size - 2]) { // special case: beyond right end
1950  i = size - 2;
1951  }
1952  else {
1953  while (x > xData[i + 1])
1954  i++;
1955  }
1956  double xL = xData[i];
1957  double xR = xData[i + 1]; // points on either side (unless beyond ends)
1958  double yL1 = yData1[i];
1959  double yR1 = yData1[i + 1];
1960  double yL2 = yData2[i];
1961  double yR2 = yData2[i + 1];
1962  double yL3 = yData3[i];
1963  double yR3 = yData3[i + 1];
1964 
1965  if (!extrapolate) { // if beyond ends of array and not extrapolating
1966  if (x < xL) {
1967  inter[0] = yL1;
1968  inter[1] = yL2;
1969  inter[2] = yL3;
1970  return;
1971  }
1972  if (x > xR) {
1973  inter[0] = yL1;
1974  inter[1] = yL2;
1975  inter[2] = yL3;
1976  return;
1977  }
1978  }
1979  const double m = (x - xL) / (xR - xL);
1980  inter[0] = m * (yR1 - yL1) + yL1;
1981  inter[1] = m * (yR2 - yL2) + yL2;
1982  inter[2] = m * (yR3 - yL3) + yL3;
1983  }
Float_t x
Definition: compare.C:6
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
G4bool larg4::OpFastScintillation::IsApplicable ( const G4ParticleDefinition &  aParticleType)
inlinevirtual

Definition at line 458 of file OpFastScintillation.hh.

459  {
460  if (aParticleType.GetParticleName() == "opticalphoton") return false;
461  if (aParticleType.IsShortLived()) return false;
462 
463  return true;
464  }
bool larg4::OpFastScintillation::isOpDetInSameTPC ( geo::Point_t const &  ScintPoint,
geo::Point_t const &  OpDetPoint 
) const
private

Definition at line 1809 of file OpFastScintillation.cxx.

References util::abs().

Referenced by detectedDirectHits(), detectedReflecHits(), and RecordPhotonsProduced().

1811  {
1812  // check optical channel is in same TPC as scintillation light, if not return 0 hits
1813  // temporary method working for SBND, uBooNE, DUNE 1x2x6; to be replaced to work in full DUNE geometry
1814  // check x coordinate has same sign or is close to zero, otherwise return 0 hits
1815  if (((ScintPoint.X() < 0.) != (OpDetPoint.X() < 0.)) &&
1816  std::abs(OpDetPoint.X()) > 10.) { // TODO: unhardcode
1817  return false;
1818  }
1819  return true;
1820  }
constexpr auto abs(T v)
Returns the absolute value of the argument.
bool larg4::OpFastScintillation::isScintInActiveVolume ( geo::Point_t const &  ScintPoint)
private

Definition at line 1822 of file OpFastScintillation.cxx.

References fActiveVolumes.

Referenced by RecordPhotonsProduced().

1823  {
1824  //semi-analytic approach only works in the active volume
1825  return fActiveVolumes[0].ContainsPosition(ScintPoint);
1826  }
std::vector< geo::BoxBoundedGeo > const fActiveVolumes
double larg4::OpFastScintillation::Omega_Dome_Model ( const double  distance,
const double  theta 
) const
private

Definition at line 2118 of file OpFastScintillation.cxx.

References fradius, and util::pi().

Referenced by VISHits(), and VUVHits().

2119  {
2120  // this function calculates the solid angle of a semi-sphere of radius b,
2121  // as a correction to the analytic formula of the on-axix solid angle,
2122  // as we move off-axis an angle theta. We have used 9-angular bins
2123  // with delta_theta width.
2124 
2125  // par0 = Radius correction close
2126  // par1 = Radius correction far
2127  // par2 = breaking distance betwween "close" and "far"
2128 
2129  double par0[9] = {0., 0., 0., 0., 0., 0.597542, 1.00872, 1.46993, 2.04221};
2130  double par1[9] = {0, 0, 0.19569, 0.300449, 0.555598, 0.854939, 1.39166, 2.19141, 2.57732};
2131  const double delta_theta = 10.;
2132  int j = int(theta / delta_theta);
2133  // PMT radius
2134  const double b = fradius; // cm
2135  // distance form which the model parameters break (empirical value)
2136  const double d_break = 5 * b; //par2
2137 
2138  if (distance >= d_break) {
2139  double R_apparent_far = b - par1[j];
2140  return (2 * CLHEP::pi * (1 - std::sqrt(1 - std::pow(R_apparent_far / distance, 2))));
2141  }
2142  else {
2143  double R_apparent_close = b - par0[j];
2144  return (2 * CLHEP::pi * (1 - std::sqrt(1 - std::pow(R_apparent_close / distance, 2))));
2145  }
2146  }
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
G4VParticleChange * larg4::OpFastScintillation::PostStepDoIt ( const G4Track &  aTrack,
const G4Step &  aStep 
)
virtual

Definition at line 409 of file OpFastScintillation.cxx.

References larg4::IonizationAndScintillation::Instance(), larg4::IonizationAndScintillation::NumberScintillationPhotons(), RecordPhotonsProduced(), and larg4::IonizationAndScintillation::Reset().

Referenced by AtRestDoIt().

414  {
415  aParticleChange.Initialize(aTrack);
416  // Check that we are in a material with a properties table, if not
417  // just return
418  const G4Material* aMaterial = aTrack.GetMaterial();
419  G4MaterialPropertiesTable* aMaterialPropertiesTable = aMaterial->GetMaterialPropertiesTable();
420  if (!aMaterialPropertiesTable) return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
421 
422  G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint();
423  G4ThreeVector x0 = pPreStepPoint->GetPosition();
424  G4ThreeVector p0 = aStep.GetDeltaPosition().unit();
425 
427  // This is the old G4 way - but we do things differently - Ben J, Oct Nov 2012.
429  //
430  // if (MeanNumberOfPhotons > 10.)
431  // {
432  // G4double sigma = ResolutionScale * std::sqrt(MeanNumberOfPhotons);
433  // NumPhotons = G4int(G4RandGauss::shoot(MeanNumberOfPhotons,sigma)+0.5);
434  // }
435  // else
436  // {
437  // NumPhotons = G4int(G4Poisson(MeanNumberOfPhotons));
438  // }
439  //
440  //
441  //
442  // if (NumPhotons <= 0)
443  // {
444  // // return unchanged particle and no secondaries
445  //
446  // aParticleChange.SetNumberOfSecondaries(0);
447  //
448  // return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
449  // }
450  //
451  //
452  // aParticleChange.SetNumberOfSecondaries(NumPhotons);
453  //
454  //
455  // if (fTrackSecondariesFirst) {
456  // if (aTrack.GetTrackStatus() == fAlive )
457  // aParticleChange.ProposeTrackStatus(fSuspend);
458  // }
459  //
460  //
461  //
462  //
464  //
465 
467  // The fast sim way - Ben J, Nov 2012
469  //
470  //
471  // We don't want to produce any trackable G4 secondaries
472  aParticleChange.SetNumberOfSecondaries(0);
473 
474  // Retrieve the Scintillation Integral for this material
475  // new G4PhysicsOrderedFreeVector allocated to hold CII's
476 
477  // Some explanation for later improvements to scint yield code:
478  //
479  // What does G4 do here?
480  // It produces light in 2 steps, fast (scnt=1) then slow (scnt=2)
481  //
482  // The ratio of slow photons to fast photons is related by the yieldratio
483  // parameter. G4's poisson fluctuating scheme is a bit different to ours
484  // - we should check that they are equivalent.
485  //
486  // G4 poisson fluctuates the number of initial photons then divides them
487  // with a constant factor between fast + slow, whereas we poisson
488  // fluctuate separateyly the fast and slow detection numbers.
489  //
490 
491  // get the number of photons produced from the IonizationAndScintillation
492  // singleton
494  double MeanNumberOfPhotons =
496  // double stepEnergy = larg4::IonizationAndScintillation::Instance()->VisibleEnergyDeposit()/CLHEP::MeV;
497  RecordPhotonsProduced(aStep, MeanNumberOfPhotons); //, stepEnergy);
498  if (verboseLevel > 0) {
499  G4cout << "\n Exiting from OpFastScintillation::DoIt -- NumberOfSecondaries = "
500  << aParticleChange.GetNumberOfSecondaries() << G4endl;
501  }
502  return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
503  }
bool RecordPhotonsProduced(const G4Step &aStep, double N)
static IonizationAndScintillation * Instance()
void larg4::OpFastScintillation::ProcessStep ( const G4Step &  step)
private

Definition at line 505 of file OpFastScintillation.cxx.

References larg4::OpDetPhotonTable::AddEnergyDeposit(), larg4::ParticleListAction::GetCurrentOrigTrackID(), larg4::ParticleListAction::GetCurrentTrackID(), and larg4::OpDetPhotonTable::Instance().

Referenced by RecordPhotonsProduced().

506  {
507  if (step.GetTotalEnergyDeposit() <= 0) return;
508 
510  -1,
511  -1,
512  1.0, //scintillation yield
513  (double)(step.GetTotalEnergyDeposit() / CLHEP::MeV), //energy in MeV
514  (float)(step.GetPreStepPoint()->GetPosition().x() / CLHEP::cm),
515  (float)(step.GetPreStepPoint()->GetPosition().y() / CLHEP::cm),
516  (float)(step.GetPreStepPoint()->GetPosition().z() / CLHEP::cm),
517  (float)(step.GetPostStepPoint()->GetPosition().x() / CLHEP::cm),
518  (float)(step.GetPostStepPoint()->GetPosition().y() / CLHEP::cm),
519  (float)(step.GetPostStepPoint()->GetPosition().z() / CLHEP::cm),
520  (double)(step.GetPreStepPoint()->GetGlobalTime()),
521  (double)(step.GetPostStepPoint()->GetGlobalTime()),
522  //step.GetTrack()->GetTrackID(),
524  step.GetTrack()->GetParticleDefinition()->GetPDGEncoding(),
526  step.GetPreStepPoint()->GetPhysicalVolume()->GetName());
527  }
static OpDetPhotonTable * Instance(bool LitePhotons=false)
void AddEnergyDeposit(int n_photon, int n_elec, double scint_yield, double energy, float start_x, float start_y, float start_z, float end_x, float end_y, float end_z, double start_time, double end_time, int trackid, int pdgcode, int g4trackid, std::string const &vol="EMPTY")
void larg4::OpFastScintillation::propagationTime ( std::vector< double > &  arrival_time_dist,
G4ThreeVector  x0,
const size_t  OpChannel,
bool  Reflected = false 
)
private

Definition at line 1009 of file OpFastScintillation.cxx.

References util::abs(), fangle_bin_timing_vuv, larg4::fast_acos(), fOpDetCenter, fPVS, getVISTimes(), getVUVTimes(), phot::PhotonVisibilityService::IncludeParPropTime(), phot::PhotonVisibilityService::IncludePropTime(), ParPropTimeTF1, util::pi(), and geo::vect::toTVector3().

Referenced by RecordPhotonsProduced().

1013  {
1014  assert(fPVS);
1016  throw cet::exception("OpFastScintillation")
1017  << "Cannot have both propagation time models simultaneously.";
1018  }
1019  else if (fPVS->IncludeParPropTime() &&
1020  !(ParPropTimeTF1 && (ParPropTimeTF1[OpChannel].GetNdim() == 1))) {
1021  //Warning: TF1::GetNdim()==1 will tell us if the TF1 is really defined or it is the default one.
1022  //This will fix a segfault when using timing and interpolation.
1023  G4cout << "WARNING: Requested parameterized timing, but no function found. Not applying "
1024  "propagation time."
1025  << G4endl;
1026  }
1027  else if (fPVS->IncludeParPropTime()) {
1028  if (Reflected)
1029  throw cet::exception("OpFastScintillation")
1030  << "No parameterized propagation time for reflected light";
1031  for (size_t i = 0; i < arrival_time_dist.size(); ++i) {
1032  arrival_time_dist[i] = ParPropTimeTF1[OpChannel].GetRandom();
1033  }
1034  }
1035  else if (fPVS->IncludePropTime()) {
1036  // Get VUV photons arrival time distribution from the parametrization
1037  geo::Point_t const& opDetCenter = fOpDetCenter.at(OpChannel);
1038  if (!Reflected) {
1039  const G4ThreeVector OpDetPoint(
1040  opDetCenter.X() * CLHEP::cm, opDetCenter.Y() * CLHEP::cm, opDetCenter.Z() * CLHEP::cm);
1041  double distance_in_cm = (x0 - OpDetPoint).mag() / CLHEP::cm; // this must be in CENTIMETERS!
1042  double cosine = std::abs(x0[0] * CLHEP::cm - OpDetPoint[0] * CLHEP::cm) / distance_in_cm;
1043  double theta = fast_acos(cosine) * 180. / CLHEP::pi;
1044  int angle_bin = theta / fangle_bin_timing_vuv;
1045  getVUVTimes(arrival_time_dist, distance_in_cm, angle_bin); // in ns
1046  }
1047  else {
1048  TVector3 const ScintPoint(x0[0] / CLHEP::cm, x0[1] / CLHEP::cm, x0[2] / CLHEP::cm); // in cm
1049  getVISTimes(arrival_time_dist, ScintPoint, geo::vect::toTVector3(opDetCenter)); // in ns
1050  }
1051  }
1052  }
std::vector< geo::Point_t > fOpDetCenter
constexpr auto abs(T v)
Returns the absolute value of the argument.
void getVISTimes(std::vector< double > &arrivalTimes, const TVector3 &ScintPoint, const TVector3 &OpDetPoint)
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:180
void getVUVTimes(std::vector< double > &arrivalTimes, const double distance_in_cm, const size_t angle_bin)
TVector3 toTVector3(Vector const &v)
Converts a vector into a TVector3.
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
phot::PhotonVisibilityService const *const fPVS
Photon visibility service instance.
phot::MappedFunctions_t ParPropTimeTF1
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
double fast_acos(double x)
bool larg4::OpFastScintillation::RecordPhotonsProduced ( const G4Step &  aStep,
double  N 
)
protected

Definition at line 529 of file OpFastScintillation.cxx.

References larg4::OpDetPhotonTable::AddLitePhoton(), larg4::OpDetPhotonTable::AddOpDetBacktrackerRecord(), larg4::OpDetPhotonTable::AddPhoton(), sim::OpDetBacktrackerRecord::AddScintillationPhotons(), average_position(), bPropagate, util::counter(), detectedDirectHits(), detectedReflecHits(), emSaturation, sim::OnePhoton::Energy, ExcitationRatio, fFiniteRiseTime, sim::LArG4Parameters::FillSimEnergyDeposits(), fOnlyActiveVolume, fOpaqueCathode, fOpDetCenter, fPVS, phot::PhotonVisibilityService::GetAllVisibilities(), larg4::ParticleListAction::GetCurrentTrackID(), phot::PhotonVisibilityService::GetReflT0s(), phot::PhotonVisibilityService::GetTimingTF1(), phot::PhotonVisibilityService::IncludeParPropTime(), sim::OnePhoton::InitialPosition, larg4::IonizationAndScintillation::Instance(), larg4::OpDetPhotonTable::Instance(), isOpDetInSameTPC(), isScintInActiveVolume(), sim::OnePhoton::MotherTrackID, phot::PhotonVisibilityService::NOpChannels(), ParPropTimeTF1, ProcessStep(), propagationTime(), reemission_energy(), ReflT0s, scint_time(), scintillationByParticleType, sim::OnePhoton::SetInSD, phot::PhotonVisibilityService::StoreReflected(), phot::PhotonVisibilityService::StoreReflT0(), theFastIntegralTable, theSlowIntegralTable, sim::OnePhoton::Time, sim::LArG4Parameters::UseLitePhotons(), usesSemiAnalyticModel(), and larg4::IonizationAndScintillation::VisibleEnergyDeposit().

Referenced by PostStepDoIt().

531  {
532  // make sure that whatever happens afterwards, the energy deposition is stored
534  if (lgp->FillSimEnergyDeposits()) ProcessStep(aStep);
535 
536  // Get the pointer to the fast scintillation table
537  OpDetPhotonTable* fst = OpDetPhotonTable::Instance();
538 
539  const G4Track* aTrack = aStep.GetTrack();
540 
541  G4StepPoint const* pPreStepPoint = aStep.GetPreStepPoint();
542  // unused G4StepPoint const* pPostStepPoint = aStep.GetPostStepPoint();
543 
544  const G4DynamicParticle* aParticle = aTrack->GetDynamicParticle();
545  const G4Material* aMaterial = aTrack->GetMaterial();
546 
547  G4int materialIndex = aMaterial->GetIndex();
548  G4int tracknumber = aStep.GetTrack()->GetTrackID();
549 
550  G4ThreeVector x0 = pPreStepPoint->GetPosition();
551  G4ThreeVector p0 = aStep.GetDeltaPosition().unit();
552  //G4double t0 = pPreStepPoint->GetGlobalTime() - fGlobalTimeOffset;
553  G4double t0 = pPreStepPoint->GetGlobalTime();
554 
555  G4MaterialPropertiesTable* aMaterialPropertiesTable = aMaterial->GetMaterialPropertiesTable();
556 
557  G4MaterialPropertyVector* Fast_Intensity =
558  aMaterialPropertiesTable->GetProperty("FASTCOMPONENT");
559  G4MaterialPropertyVector* Slow_Intensity =
560  aMaterialPropertiesTable->GetProperty("SLOWCOMPONENT");
561 
562  if (!Fast_Intensity && !Slow_Intensity) return 1;
563 
564  if (!bPropagate) return 0;
565 
566  // Get the visibility vector for this point
567  assert(fPVS);
568 
569  G4int nscnt = 1;
570  if (Fast_Intensity && Slow_Intensity) nscnt = 2;
571 
572  double Num = 0;
573  double YieldRatio = 0;
574 
576  // The scintillation response is a function of the energy
577  // deposited by particle types.
578 
579  // Get the definition of the current particle
580  G4ParticleDefinition* pDef = aParticle->GetDefinition();
581 
582  // Obtain the G4MaterialPropertyVectory containing the
583  // scintillation light yield as a function of the deposited
584  // energy for the current particle type
585 
586  // Protons
587  if (pDef == G4Proton::ProtonDefinition()) {
588  YieldRatio = aMaterialPropertiesTable->GetConstProperty("PROTONYIELDRATIO");
589  }
590  // Muons
591  else if (pDef == G4MuonPlus::MuonPlusDefinition() ||
592  pDef == G4MuonMinus::MuonMinusDefinition()) {
593  YieldRatio = aMaterialPropertiesTable->GetConstProperty("MUONYIELDRATIO");
594  }
595  // Pions
596  else if (pDef == G4PionPlus::PionPlusDefinition() ||
597  pDef == G4PionMinus::PionMinusDefinition()) {
598  YieldRatio = aMaterialPropertiesTable->GetConstProperty("PIONYIELDRATIO");
599  }
600  // Kaons
601  else if (pDef == G4KaonPlus::KaonPlusDefinition() ||
602  pDef == G4KaonMinus::KaonMinusDefinition()) {
603  YieldRatio = aMaterialPropertiesTable->GetConstProperty("KAONYIELDRATIO");
604  }
605  // Alphas
606  else if (pDef == G4Alpha::AlphaDefinition()) {
607  YieldRatio = aMaterialPropertiesTable->GetConstProperty("ALPHAYIELDRATIO");
608  }
609  // Electrons (must also account for shell-binding energy
610  // attributed to gamma from standard PhotoElectricEffect)
611  else if (pDef == G4Electron::ElectronDefinition() || pDef == G4Gamma::GammaDefinition()) {
612  YieldRatio = aMaterialPropertiesTable->GetConstProperty("ELECTRONYIELDRATIO");
613  }
614  // Default for particles not enumerated/listed above
615  else {
616  YieldRatio = aMaterialPropertiesTable->GetConstProperty("ELECTRONYIELDRATIO");
617  }
618  // If the user has not specified yields for (p,d,t,a,carbon)
619  // then these unspecified particles will default to the
620  // electron's scintillation yield
621  if (YieldRatio == 0) {
622  YieldRatio = aMaterialPropertiesTable->GetConstProperty("ELECTRONYIELDRATIO");
623  }
624  }
625 
626  geo::Point_t const ScintPoint = {x0[0] / CLHEP::cm, x0[1] / CLHEP::cm, x0[2] / CLHEP::cm};
627  if (fOnlyActiveVolume && !isScintInActiveVolume(ScintPoint)) return 0;
628  const phot::MappedCounts_t& Visibilities = fPVS->GetAllVisibilities(ScintPoint);
629 
630  phot::MappedCounts_t ReflVisibilities;
631 
632  // Store timing information in the object for use in propagationTime method
633  if (fPVS->StoreReflected()) {
634  ReflVisibilities = fPVS->GetAllVisibilities(ScintPoint, true);
635  if (fPVS->StoreReflT0()) ReflT0s = fPVS->GetReflT0s(ScintPoint);
636  }
637  if (fPVS->IncludeParPropTime()) { ParPropTimeTF1 = fPVS->GetTimingTF1(ScintPoint); }
638 
639  /*
640  // For Kazu to debug # photons generated using csv file, by default should be commented out
641  // but don't remove as it's useful. Separated portion of code relevant to this block
642  // is labeled as "CASE-DEBUG DO NOT REMOVE THIS COMMENT"
643  // (2017 May 2nd ... "kazuhiro at nevis dot columbia dot edu")
644  //
645  static bool first_time=false;
646  if(!first_time) {
647  std::cout<<"LOGMEid,pdg,mass,ke,te,de,x,y,z,t,dr,mean_npe,gen_npe,det_npe"<<std::endl;
648  first_time=true;
649  }
650 
651  std::cout<<"LOGME"
652  <<aStep.GetTrack()->GetTrackID()<<","
653  <<aParticle->GetDefinition()->GetPDGEncoding()<<","
654  <<aParticle->GetDefinition()->GetPDGMass()/CLHEP::MeV<<","
655  <<pPreStepPoint->GetKineticEnergy()<<","
656  <<pPreStepPoint->GetTotalEnergy()<<","
657  <<aStep.GetTotalEnergyDeposit()<<","
658  <<ScintPoint<<","<<t0<<","
659  <<aStep.GetDeltaPosition().mag()<<","
660  <<MeanNumberOfPhotons<<","<<std::flush;
661 
662  double gen_photon_ctr=0;
663  double det_photon_ctr=0;
664  */
665  for (G4int scnt = 1; scnt <= nscnt; scnt++) {
666  G4double ScintillationTime = 0. * CLHEP::ns;
667  G4double ScintillationRiseTime = 0. * CLHEP::ns;
668  G4PhysicsOrderedFreeVector* ScintillationIntegral = NULL;
669  if (scnt == 1) {
670  if (nscnt == 1) {
671  if (Fast_Intensity) {
672  ScintillationTime = aMaterialPropertiesTable->GetConstProperty("FASTTIMECONSTANT");
673  if (fFiniteRiseTime) {
674  ScintillationRiseTime =
675  aMaterialPropertiesTable->GetConstProperty("FASTSCINTILLATIONRISETIME");
676  }
677  ScintillationIntegral =
678  (G4PhysicsOrderedFreeVector*)((*theFastIntegralTable)(materialIndex));
679  }
680  if (Slow_Intensity) {
681  ScintillationTime = aMaterialPropertiesTable->GetConstProperty("SLOWTIMECONSTANT");
682  if (fFiniteRiseTime) {
683  ScintillationRiseTime =
684  aMaterialPropertiesTable->GetConstProperty("SLOWSCINTILLATIONRISETIME");
685  }
686  ScintillationIntegral =
687  (G4PhysicsOrderedFreeVector*)((*theSlowIntegralTable)(materialIndex));
688  }
689  } //endif nscnt=1
690  else {
691  if (YieldRatio == 0)
692  YieldRatio = aMaterialPropertiesTable->GetConstProperty("YIELDRATIO");
693 
694  if (ExcitationRatio == 1.0) { Num = std::min(YieldRatio, 1.0) * MeanNumberOfPhotons; }
695  else {
696  Num = std::min(ExcitationRatio, 1.0) * MeanNumberOfPhotons;
697  }
698  ScintillationTime = aMaterialPropertiesTable->GetConstProperty("FASTTIMECONSTANT");
699  if (fFiniteRiseTime) {
700  ScintillationRiseTime =
701  aMaterialPropertiesTable->GetConstProperty("FASTSCINTILLATIONRISETIME");
702  }
703  ScintillationIntegral =
704  (G4PhysicsOrderedFreeVector*)((*theFastIntegralTable)(materialIndex));
705  } //endif nscnt!=1
706  } //end scnt=1
707 
708  else {
709  Num = MeanNumberOfPhotons - Num;
710  ScintillationTime = aMaterialPropertiesTable->GetConstProperty("SLOWTIMECONSTANT");
711  if (fFiniteRiseTime) {
712  ScintillationRiseTime =
713  aMaterialPropertiesTable->GetConstProperty("SLOWSCINTILLATIONRISETIME");
714  }
715  ScintillationIntegral =
716  (G4PhysicsOrderedFreeVector*)((*theSlowIntegralTable)(materialIndex));
717  }
718 
719  if (!ScintillationIntegral) continue;
720  //gen_photon_ctr += Num; // CASE-DEBUG DO NOT REMOVE THIS COMMENT
721  // Max Scintillation Integral
722  // G4double CIImax = ScintillationIntegral->GetMaxValue();
723  //std::cout << "++++++++++++" << Num << "++++++++++" << std::endl;
724 
725  // here we go: now if visibilities are invalid, we are in trouble
726  //if (!Visibilities && (fPVS->NOpChannels() > 0)) {
727  // throw cet::exception("OpFastScintillator")
728  // << "Photon library does not cover point " << ScintPoint << " cm.\n";
729  //}
730 
731  if (!Visibilities && !usesSemiAnalyticModel()) continue;
732 
733  // detected photons from direct light
734  std::map<size_t, int> DetectedNum;
735  if (Visibilities && !usesSemiAnalyticModel()) {
736  for (size_t const OpDet : util::counter(fPVS->NOpChannels())) {
737  if (fOpaqueCathode && !isOpDetInSameTPC(ScintPoint, fOpDetCenter.at(OpDet))) continue;
738  int const DetThis = std::round(G4Poisson(Visibilities[OpDet] * Num));
739  if (DetThis > 0) DetectedNum[OpDet] = DetThis;
740  }
741  }
742  else {
743  detectedDirectHits(DetectedNum, Num, ScintPoint);
744  }
745 
746  // detected photons from reflected light
747  std::map<size_t, int> ReflDetectedNum;
748  if (fPVS->StoreReflected()) {
749  if (!usesSemiAnalyticModel()) {
750  for (size_t const OpDet : util::counter(fPVS->NOpChannels())) {
751  if (fOpaqueCathode && !isOpDetInSameTPC(ScintPoint, fOpDetCenter.at(OpDet))) continue;
752  int const ReflDetThis = std::round(G4Poisson(ReflVisibilities[OpDet] * Num));
753  if (ReflDetThis > 0) ReflDetectedNum[OpDet] = ReflDetThis;
754  }
755  }
756  else {
757  detectedReflecHits(ReflDetectedNum, Num, ScintPoint);
758  }
759  }
760 
761  std::vector<double> arrival_time_dist;
762  // Now we run through each PMT figuring out num of detected photons
763  for (size_t Reflected = 0; Reflected <= 1; ++Reflected) {
764  // Only do the reflected loop if we have reflected visibilities
765  if (Reflected && !fPVS->StoreReflected()) continue;
766 
769  if (Reflected) {
770  itstart = ReflDetectedNum.begin();
771  itend = ReflDetectedNum.end();
772  }
773  else {
774  itstart = DetectedNum.begin();
775  itend = DetectedNum.end();
776  }
777  for (auto itdetphot = itstart; itdetphot != itend; ++itdetphot) {
778  const size_t OpChannel = itdetphot->first;
779  const int NPhotons = itdetphot->second;
780 
781  // Set up the OpDetBTR information
782  sim::OpDetBacktrackerRecord tmpOpDetBTRecord(OpChannel);
783  int thisG4TrackID = ParticleListAction::GetCurrentTrackID();
784  double xyzPos[3];
785  average_position(aStep, xyzPos);
786  double Edeposited = 0;
788  //We use this when it is the only sensical information. It may be of limited use to end users.
789  Edeposited = aStep.GetTotalEnergyDeposit();
790  }
791  else if (emSaturation) {
792  //If Birk Coefficient used, log VisibleEnergies.
793  Edeposited =
795  }
796  else {
797  //We use this when it is the only sensical information. It may be of limited use to end users.
798  Edeposited = aStep.GetTotalEnergyDeposit();
799  }
800 
801  // Get the transport time distribution
802  arrival_time_dist.resize(NPhotons);
803  propagationTime(arrival_time_dist, x0, OpChannel, Reflected);
804 
805  //We need to split the energy up by the number of photons so that we never try to write a 0 energy.
806  Edeposited = Edeposited / double(NPhotons);
807 
808  // Loop through the photons
809  for (G4int i = 0; i < NPhotons; ++i) {
810  //std::cout<<"VUV time correction: "<<arrival_time_dist[i]<<std::endl;
811  G4double Time = t0 + scint_time(aStep, ScintillationTime, ScintillationRiseTime) +
812  arrival_time_dist[i] * CLHEP::ns;
813 
814  // Always store the BTR
815  tmpOpDetBTRecord.AddScintillationPhotons(thisG4TrackID, Time, 1, xyzPos, Edeposited);
816 
817  // Store as lite photon or as OnePhoton
818  if (lgp->UseLitePhotons()) {
819  fst->AddLitePhoton(OpChannel, static_cast<int>(Time), 1, Reflected);
820  }
821  else {
822  // The sim photon in this case stores its production point and time
823  TVector3 PhotonPosition(x0[0], x0[1], x0[2]);
824 
825  float PhotonEnergy = 0;
826  if (Reflected)
827  PhotonEnergy = reemission_energy() * CLHEP::eV;
828  else
829  PhotonEnergy = 9.7 * CLHEP::eV; // 9.7 eV peak of VUV emission spectrum
830 
831  // Make a photon object for the collection
832  sim::OnePhoton PhotToAdd;
833  PhotToAdd.InitialPosition = PhotonPosition;
834  PhotToAdd.Energy = PhotonEnergy;
835  PhotToAdd.Time = Time;
836  PhotToAdd.SetInSD = false;
837  PhotToAdd.MotherTrackID = tracknumber;
838 
839  fst->AddPhoton(OpChannel, std::move(PhotToAdd), Reflected);
840  }
841  }
842  fst->AddOpDetBacktrackerRecord(tmpOpDetBTRecord, Reflected);
843  }
844  }
845  }
846  //std::cout<<gen_photon_ctr<<","<<det_photon_ctr<<std::endl; // CASE-DEBUG DO NOT REMOVE THIS COMMENT
847  return 0;
848  }
code to link reconstructed objects back to the MC truth information
void detectedDirectHits(std::map< size_t, int > &DetectedNum, const double Num, geo::Point_t const &ScintPoint) const
void detectedReflecHits(std::map< size_t, int > &ReflDetectedNum, const double Num, geo::Point_t const &ScintPoint) const
void average_position(G4Step const &aStep, double *xzyPos) const
bool isScintInActiveVolume(geo::Point_t const &ScintPoint)
std::vector< geo::Point_t > fOpDetCenter
void propagationTime(std::vector< double > &arrival_time_dist, G4ThreeVector x0, const size_t OpChannel, bool Reflected=false)
bool const fOnlyActiveVolume
Whether photon propagation is performed only from active volumes.
All information of a photon entering the sensitive optical detector volume.
Definition: SimPhotons.h:60
bool isOpDetInSameTPC(geo::Point_t const &ScintPoint, geo::Point_t const &OpDetPoint) const
MappedFunctions_t GetTimingTF1(Point const &p) const
void ProcessStep(const G4Step &step)
std::unique_ptr< G4PhysicsTable > theSlowIntegralTable
intermediate_table::const_iterator const_iterator
G4double scint_time(const G4Step &aStep, G4double ScintillationTime, G4double ScintillationRiseTime) const
Energy deposited on a readout Optical Detector by simulated tracks.
geo::Point_t InitialPosition
Scintillation position in world coordinates [cm].
Definition: SimPhotons.h:63
bool const bPropagate
Whether propagation of photons is enabled.
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:295
bool usesSemiAnalyticModel() const
Returns whether the semi-analytic visibility parametrization is being used.
MappedT0s_t GetReflT0s(Point const &p) const
static IonizationAndScintillation * Instance()
bool FillSimEnergyDeposits() const
MappedCounts_t GetAllVisibilities(Point const &p, bool wantReflected=false) const
static OpDetPhotonTable * Instance(bool LitePhotons=false)
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:180
A container for photon visibility mapping data.
bool SetInSD
Whether the photon reaches the sensitive detector.
Definition: SimPhotons.h:84
phot::PhotonVisibilityService const *const fPVS
Photon visibility service instance.
bool const fOpaqueCathode
Whether the cathodes are fully opaque; currently hard coded "no".
float Energy
Scintillation photon energy [GeV].
Definition: SimPhotons.h:78
phot::MappedFunctions_t ParPropTimeTF1
bool UseLitePhotons() const
std::unique_ptr< G4PhysicsTable > theFastIntegralTable
int MotherTrackID
ID of the GEANT4 track causing the scintillation.
Definition: SimPhotons.h:81
double larg4::OpFastScintillation::Rectangle_SolidAngle ( const double  a,
const double  b,
const double  d 
) const
private

Definition at line 2051 of file OpFastScintillation.cxx.

References d, and larg4::fast_acos().

Referenced by detectedReflecHits(), Rectangle_SolidAngle(), VISHits(), and VUVHits().

2054  {
2055  double aa = a / (2. * d);
2056  double bb = b / (2. * d);
2057  double aux = (1. + aa * aa + bb * bb) / ((1. + aa * aa) * (1. + bb * bb));
2058  // return 4 * std::acos(std::sqrt(aux));
2059  return 4. * fast_acos(std::sqrt(aux));
2060  }
Float_t d
Definition: plot.C:235
double fast_acos(double x)
double larg4::OpFastScintillation::Rectangle_SolidAngle ( Dims const &  o,
const std::array< double, 3 >  v 
) const
private

Definition at line 2063 of file OpFastScintillation.cxx.

References larg4::OpFastScintillation::Dims::h, larg4::isApproximatelyZero(), larg4::isDefinitelyGreaterThan(), Rectangle_SolidAngle(), and larg4::OpFastScintillation::Dims::w.

2065  {
2066  // v is the position of the track segment with respect to
2067  // the center position of the arapuca window
2068 
2069  // arapuca plane fixed in x direction
2070  if (isApproximatelyZero(v[1]) && isApproximatelyZero(v[2])) {
2071  return Rectangle_SolidAngle(o.h, o.w, v[0]);
2072  }
2073  if (isDefinitelyGreaterThan(v[1], o.h * .5) && isDefinitelyGreaterThan(v[2], o.w * .5)) {
2074  double A = v[1] - o.h * .5;
2075  double B = v[2] - o.w * .5;
2076  double to_return = (Rectangle_SolidAngle(2. * (A + o.h), 2. * (B + o.w), v[0]) -
2077  Rectangle_SolidAngle(2. * A, 2. * (B + o.w), v[0]) -
2078  Rectangle_SolidAngle(2. * (A + o.h), 2. * B, v[0]) +
2079  Rectangle_SolidAngle(2. * A, 2. * B, v[0])) *
2080  .25;
2081  return to_return;
2082  }
2083  if ((v[1] <= o.h * .5) && (v[2] <= o.w * .5)) {
2084  double A = -v[1] + o.h * .5;
2085  double B = -v[2] + o.w * .5;
2086  double to_return = (Rectangle_SolidAngle(2. * (o.h - A), 2. * (o.w - B), v[0]) +
2087  Rectangle_SolidAngle(2. * A, 2. * (o.w - B), v[0]) +
2088  Rectangle_SolidAngle(2. * (o.h - A), 2. * B, v[0]) +
2089  Rectangle_SolidAngle(2. * A, 2. * B, v[0])) *
2090  .25;
2091  return to_return;
2092  }
2093  if (isDefinitelyGreaterThan(v[1], o.h * .5) && (v[2] <= o.w * .5)) {
2094  double A = v[1] - o.h * .5;
2095  double B = -v[2] + o.w * .5;
2096  double to_return = (Rectangle_SolidAngle(2. * (A + o.h), 2. * (o.w - B), v[0]) -
2097  Rectangle_SolidAngle(2. * A, 2. * (o.w - B), v[0]) +
2098  Rectangle_SolidAngle(2. * (A + o.h), 2. * B, v[0]) -
2099  Rectangle_SolidAngle(2. * A, 2. * B, v[0])) *
2100  .25;
2101  return to_return;
2102  }
2103  if ((v[1] <= o.h * .5) && isDefinitelyGreaterThan(v[2], o.w * .5)) {
2104  double A = -v[1] + o.h * .5;
2105  double B = v[2] - o.w * .5;
2106  double to_return = (Rectangle_SolidAngle(2. * (o.h - A), 2. * (B + o.w), v[0]) -
2107  Rectangle_SolidAngle(2. * (o.h - A), 2. * B, v[0]) +
2108  Rectangle_SolidAngle(2. * A, 2. * (B + o.w), v[0]) -
2109  Rectangle_SolidAngle(2. * A, 2. * B, v[0])) *
2110  .25;
2111  return to_return;
2112  }
2113  // error message if none of these cases, i.e. something has gone wrong!
2114  // std::cout << "Warning: invalid solid angle call." << std::endl;
2115  return 0.;
2116  }
static constexpr bool isDefinitelyGreaterThan(TReal a, TReal b, TReal tolerance=std::numeric_limits< TReal >::epsilon())
double Rectangle_SolidAngle(const double a, const double b, const double d) const
static constexpr bool isApproximatelyZero(TReal a, TReal tolerance=std::numeric_limits< TReal >::epsilon())
double larg4::OpFastScintillation::reemission_energy ( ) const
private

Definition at line 1074 of file OpFastScintillation.cxx.

References fTPBEm, and tpbemission.

Referenced by RecordPhotonsProduced().

1075  {
1076  return fTPBEm->fire() * ((*(--tpbemission.end())).first - (*tpbemission.begin()).first) +
1077  (*tpbemission.begin()).first;
1078  }
std::map< double, double > tpbemission
std::unique_ptr< CLHEP::RandGeneral > fTPBEm
void larg4::OpFastScintillation::RemoveSaturation ( )
inline

Definition at line 218 of file OpFastScintillation.hh.

Referenced by SetScintillationByParticleType().

218 { emSaturation = NULL; }
G4double larg4::OpFastScintillation::sample_time ( const G4double  tau1,
const G4double  tau2 
) const
private

Definition at line 1054 of file OpFastScintillation.cxx.

References bi_exp(), d, and single_exp().

Referenced by scint_time().

1055  {
1056  // tau1: rise time and tau2: decay time
1057  while (1) {
1058  // two random numbers
1059  G4double ran1 = G4UniformRand();
1060  G4double ran2 = G4UniformRand();
1061  //
1062  // exponential distribution as envelope function: very efficient
1063  //
1064  G4double d = (tau1 + tau2) / tau2;
1065  // make sure the envelope function is
1066  // always larger than the bi-exponential
1067  G4double t = -1.0 * tau2 * std::log(1 - ran1);
1068  G4double g = d * single_exp(t, tau2);
1069  if (ran2 <= bi_exp(t, tau1, tau2) / g) return t;
1070  }
1071  return -1.0;
1072  }
G4double bi_exp(const G4double t, const G4double tau1, const G4double tau2) const
Float_t d
Definition: plot.C:235
G4double single_exp(const G4double t, const G4double tau2) const
G4double larg4::OpFastScintillation::scint_time ( const G4Step &  aStep,
G4double  ScintillationTime,
G4double  ScintillationRiseTime 
) const
private

Definition at line 992 of file OpFastScintillation.cxx.

References sample_time().

Referenced by RecordPhotonsProduced().

995  {
996  G4StepPoint const* pPreStepPoint = aStep.GetPreStepPoint();
997  G4StepPoint const* pPostStepPoint = aStep.GetPostStepPoint();
998  G4double avgVelocity = (pPreStepPoint->GetVelocity() + pPostStepPoint->GetVelocity()) / 2.;
999  G4double deltaTime = aStep.GetStepLength() / avgVelocity;
1000  if (ScintillationRiseTime == 0.0) {
1001  deltaTime = deltaTime - ScintillationTime * std::log(G4UniformRand());
1002  }
1003  else {
1004  deltaTime = deltaTime + sample_time(ScintillationRiseTime, ScintillationTime);
1005  }
1006  return deltaTime;
1007  }
G4double sample_time(const G4double tau1, const G4double tau2) const
void larg4::OpFastScintillation::SetFiniteRiseTime ( const G4bool  state)
inline

Definition at line 471 of file OpFastScintillation.hh.

472  {
473  fFiniteRiseTime = state;
474  }
void larg4::OpFastScintillation::SetScintillationByParticleType ( const G4bool  scintType)

Definition at line 966 of file OpFastScintillation.cxx.

References emSaturation, RemoveSaturation(), and scintillationByParticleType.

967  {
968  if (emSaturation) {
969  G4Exception("OpFastScintillation::SetScintillationByParticleType",
970  "Scint02",
971  JustWarning,
972  "Redefinition: Birks Saturation is replaced by ScintillationByParticleType!");
974  }
975  scintillationByParticleType = scintType;
976  }
void larg4::OpFastScintillation::SetScintillationExcitationRatio ( const G4double  excitationratio)
inline

Definition at line 496 of file OpFastScintillation.hh.

497  {
498  ExcitationRatio = excitationratio;
499  }
void larg4::OpFastScintillation::SetScintillationYieldFactor ( const G4double  yieldfactor)
inline

Definition at line 486 of file OpFastScintillation.hh.

487  {
488  YieldFactor = yieldfactor;
489  }
void larg4::OpFastScintillation::SetTrackSecondariesFirst ( const G4bool  state)
inline

Definition at line 466 of file OpFastScintillation.hh.

467  {
468  fTrackSecondariesFirst = state;
469  }
G4double larg4::OpFastScintillation::single_exp ( const G4double  t,
const G4double  tau2 
) const
private

Definition at line 1828 of file OpFastScintillation.cxx.

Referenced by sample_time().

1829  {
1830  return std::exp(-1.0 * t / tau2) / tau2;
1831  }
bool larg4::OpFastScintillation::usesSemiAnalyticModel ( ) const
private

Returns whether the semi-analytic visibility parametrization is being used.

Definition at line 1472 of file OpFastScintillation.cxx.

References fUseNhitsModel.

Referenced by OpFastScintillation(), and RecordPhotonsProduced().

1473  {
1474  return fUseNhitsModel;
1475  } // OpFastScintillation::usesSemiAnalyticModel()
bool const fUseNhitsModel
Whether the semi-analytic model is being used for photon visibility.
int larg4::OpFastScintillation::VISHits ( geo::Point_t const &  ScintPoint,
OpticalDetector const &  opDet,
const double  cathode_hits_rec,
const std::array< double, 3 >  hotspot 
) const
private

Definition at line 1681 of file OpFastScintillation.cxx.

References util::abs(), d, Disk_SolidAngle(), larg4::dist(), larg4::fast_acos(), fcathode_centre, fdelta_angulo_vis, geo::vect::fillCoords(), fIsDomePDCorr, fIsFlatPDCorr, fplane_depth, fradius, fvis_distances_r_dome, fvis_distances_r_flat, fvis_distances_x_dome, fvis_distances_x_flat, fvispars_dome, fvispars_flat, larg4::OpFastScintillation::OpticalDetector::h, interpolate(), Omega_Dome_Model(), larg4::OpFastScintillation::OpticalDetector::OpDetPoint, util::pi(), r, Rectangle_SolidAngle(), util::size(), larg4::OpFastScintillation::OpticalDetector::type, and larg4::OpFastScintillation::OpticalDetector::w.

Referenced by detectedReflecHits().

1685  {
1686  // 1). calculate total number of hits of VUV photons on reflective
1687  // foils via solid angle + Gaisser-Hillas corrections.
1688  // Done outside as it doesn't depend on OpDetPoint
1689 
1690  // set plane_depth for correct TPC:
1691  double plane_depth;
1692  if (ScintPoint_v.X() < 0.) { plane_depth = -fplane_depth; }
1693  else {
1694  plane_depth = fplane_depth;
1695  }
1696 
1697  // 2). calculate number of these hits which reach the optical
1698  // detector from the hotspot via solid angle
1699 
1700  // the interface has been converted into geo::Point_t, the implementation not yet
1701  std::array<double, 3U> ScintPoint;
1702  std::array<double, 3U> OpDetPoint;
1703  geo::vect::fillCoords(ScintPoint, ScintPoint_v);
1704  geo::vect::fillCoords(OpDetPoint, opDet.OpDetPoint);
1705 
1706  // calculate distances and angles for application of corrections
1707  // distance from hotspot to optical detector
1708  double distance_vis = dist(&hotspot[0], &OpDetPoint[0], 3);
1709  // angle between hotspot and optical detector
1710  double cosine_vis = std::abs(hotspot[0] - OpDetPoint[0]) / distance_vis;
1711  // double theta_vis = std::acos(cosine_vis) * 180. / CLHEP::pi;
1712  double theta_vis = fast_acos(cosine_vis) * 180. / CLHEP::pi;
1713 
1714  // calculate solid angle of optical detector
1715  double solid_angle_detector = 0;
1716  // rectangular aperture
1717  if (opDet.type == 0) {
1718  // get hotspot coordinates relative to opDet
1719  std::array<double, 3> emission_relative = {std::abs(hotspot[0] - OpDetPoint[0]),
1720  std::abs(hotspot[1] - OpDetPoint[1]),
1721  std::abs(hotspot[2] - OpDetPoint[2])};
1722  // calculate solid angle
1723  solid_angle_detector = Rectangle_SolidAngle(Dims{opDet.h, opDet.w}, emission_relative);
1724  }
1725  // dome aperture
1726  else if (opDet.type == 1) {
1727  solid_angle_detector = Omega_Dome_Model(distance_vis, theta_vis);
1728  }
1729  // disk aperture
1730  else if (opDet.type == 2) {
1731  // offset in z-y plane
1732  double d = dist(&hotspot[1], &OpDetPoint[1], 2);
1733  // drift distance (in x)
1734  double h = std::abs(hotspot[0] - OpDetPoint[0]);
1735  // calculate solid angle
1736  solid_angle_detector = Disk_SolidAngle(d, h, fradius);
1737  }
1738  else {
1739  std::cout << "Error: Invalid optical detector type. 0 = rectangular, 1 = dome, 2 = disk"
1740  << std::endl;
1741  }
1742 
1743  // calculate number of hits via geometeric acceptance
1744  double hits_geo = (solid_angle_detector / (2. * CLHEP::pi)) *
1745  cathode_hits_rec; // 2*pi due to presence of reflective foils
1746 
1747  // determine correction factor, depending on PD type
1748  const size_t k = (theta_vis / fdelta_angulo_vis); // off-set angle bin
1749  // radial distance from centre of detector (Y-Z)
1750  // FIXME (KJK): Original implementation only accounts for the Y component
1751  double r = std::abs(ScintPoint[1] - fcathode_centre.Y());
1752  double d_c = std::abs(ScintPoint[0] - plane_depth); // distance to cathode
1753  double border_correction = 0;
1754  // flat PDs
1755  if ((opDet.type == 0 || opDet.type == 2) && fIsFlatPDCorr) {
1756  // interpolate in d_c for each r bin
1757  const size_t nbins_r = fvispars_flat[k].size();
1758  std::vector<double> interp_vals(nbins_r, 0.0);
1759  {
1760  size_t idx = 0;
1761  size_t size = fvis_distances_x_flat.size();
1762  if (d_c >= fvis_distances_x_flat[size - 2])
1763  idx = size - 2;
1764  else {
1765  while (d_c > fvis_distances_x_flat[idx + 1])
1766  idx++;
1767  }
1768  for (size_t i = 0; i < nbins_r; ++i) {
1769  interp_vals[i] = interpolate(fvis_distances_x_flat, fvispars_flat[k][i], d_c, false, idx);
1770  }
1771  }
1772  // interpolate in r
1773  border_correction = interpolate(fvis_distances_r_flat, interp_vals, r, false);
1774  }
1775  // dome PDs
1776  else if (opDet.type == 1 && fIsDomePDCorr) {
1777  // interpolate in d_c for each r bin
1778  const size_t nbins_r = fvispars_dome[k].size();
1779  std::vector<double> interp_vals(nbins_r, 0.0);
1780  {
1781  size_t idx = 0;
1782  size_t size = fvis_distances_x_dome.size();
1783  if (d_c >= fvis_distances_x_dome[size - 2])
1784  idx = size - 2;
1785  else {
1786  while (d_c > fvis_distances_x_dome[idx + 1])
1787  idx++;
1788  }
1789  for (size_t i = 0; i < nbins_r; ++i) {
1790  interp_vals[i] = interpolate(fvis_distances_x_dome, fvispars_dome[k][i], d_c, false, idx);
1791  }
1792  }
1793  // interpolate in r
1794  border_correction = interpolate(fvis_distances_r_dome, interp_vals, r, false);
1795  }
1796  else {
1797  std::cout << "Error: Invalid optical detector type. 0 = rectangular, 1 = dome, 2 = disk. Or "
1798  "corrections for chosen optical detector type missing."
1799  << std::endl;
1800  }
1801 
1802  // apply correction factor
1803  double hits_rec = border_correction * hits_geo / cosine_vis;
1804  double hits_vis = std::round(G4Poisson(hits_rec));
1805 
1806  return hits_vis;
1807  }
TRandom r
Definition: spectrum.C:23
std::vector< std::vector< std::vector< double > > > fvispars_dome
std::vector< std::vector< std::vector< double > > > fvispars_flat
constexpr auto abs(T v)
Returns the absolute value of the argument.
std::vector< double > fvis_distances_r_flat
unsigned int fillCoords(Coords &dest, Vector const &src)
Fills a coordinate array with the coordinates of a vector.
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
std::vector< double > fvis_distances_x_flat
Float_t d
Definition: plot.C:235
std::vector< double > fvis_distances_r_dome
std::vector< double > fvis_distances_x_dome
double Rectangle_SolidAngle(const double a, const double b, const double d) const
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
double Omega_Dome_Model(const double distance, const double theta) const
double Disk_SolidAngle(const double d, const double h, const double b) const
double interpolate(const std::vector< double > &xData, const std::vector< double > &yData, double x, bool extrapolate, size_t i=0) const
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
double fast_acos(double x)
int larg4::OpFastScintillation::VUVHits ( const double  Nphotons_created,
geo::Point_t const &  ScintPoint,
OpticalDetector const &  opDet 
) const
private

Definition at line 1578 of file OpFastScintillation.cxx.

References util::abs(), d, Disk_SolidAngle(), larg4::dist(), larg4::fast_acos(), fborder_corr_angulo_dome, fborder_corr_angulo_flat, fborder_corr_dome, fborder_corr_flat, fcathode_centre, fdelta_angulo_vuv, fGHvuvpars_dome, fGHvuvpars_flat, geo::vect::fillCoords(), fIsDomePDCorr, fIsFlatPDCorr, fL_abs_vuv, fradius, Gaisser_Hillas(), larg4::OpFastScintillation::OpticalDetector::h, interpolate(), Omega_Dome_Model(), larg4::OpFastScintillation::OpticalDetector::OpDetPoint, util::pi(), r, Rectangle_SolidAngle(), larg4::OpFastScintillation::OpticalDetector::type, and larg4::OpFastScintillation::OpticalDetector::w.

Referenced by detectedDirectHits().

1581  {
1582  // the interface has been converted into geo::Point_t, the implementation not yet
1583  std::array<double, 3U> ScintPoint;
1584  std::array<double, 3U> OpDetPoint;
1585  geo::vect::fillCoords(ScintPoint, ScintPoint_v);
1586  geo::vect::fillCoords(OpDetPoint, opDet.OpDetPoint);
1587 
1588  // distance and angle between ScintPoint and OpDetPoint
1589  double distance = dist(&ScintPoint[0], &OpDetPoint[0], 3);
1590  double cosine = std::abs(ScintPoint[0] - OpDetPoint[0]) / distance;
1591  // double theta = std::acos(cosine) * 180. / CLHEP::pi;
1592  double theta = fast_acos(cosine) * 180. / CLHEP::pi;
1593 
1594  // calculate solid angle:
1595  double solid_angle = 0;
1596  // Arapucas/Bars (rectangle)
1597  if (opDet.type == 0) {
1598  // get scintillation point coordinates relative to arapuca window centre
1599  std::array<double, 3> ScintPoint_rel = {std::abs(ScintPoint[0] - OpDetPoint[0]),
1600  std::abs(ScintPoint[1] - OpDetPoint[1]),
1601  std::abs(ScintPoint[2] - OpDetPoint[2])};
1602  // calculate solid angle
1603  solid_angle = Rectangle_SolidAngle(Dims{opDet.h, opDet.w}, ScintPoint_rel);
1604  }
1605  // PMTs (dome)
1606  else if (opDet.type == 1) {
1607  solid_angle = Omega_Dome_Model(distance, theta);
1608  }
1609  // PMTs (disk approximation)
1610  else if (opDet.type == 2) {
1611  // offset in z-y plane
1612  double d = dist(&ScintPoint[1], &OpDetPoint[1], 2);
1613  // drift distance (in x)
1614  double h = std::abs(ScintPoint[0] - OpDetPoint[0]);
1615  // Solid angle of a disk
1616  solid_angle = Disk_SolidAngle(d, h, fradius);
1617  }
1618  else {
1619  std::cout << "Error: Invalid optical detector type. 0 = rectangular, 1 = dome, 2 = disk"
1620  << std::endl;
1621  }
1622 
1623  // calculate number of photons hits by geometric acceptance: accounting for solid angle and LAr absorbtion length
1624  double hits_geo =
1625  std::exp(-1. * distance / fL_abs_vuv) * (solid_angle / (4 * CLHEP::pi)) * Nphotons_created;
1626 
1627  // apply Gaisser-Hillas correction for Rayleigh scattering distance
1628  // and angular dependence offset angle bin
1629  const size_t j = (theta / fdelta_angulo_vuv);
1630 
1631  // determine GH parameters, accounting for border effects
1632  // radial distance from centre of detector (Y-Z)
1633  // FIXME (KJK): Original implementation only accounts for the Y component
1634  double r = std::abs(ScintPoint[1] - fcathode_centre.Y());
1635  double pars_ini[4] = {0, 0, 0, 0};
1636  double s1 = 0;
1637  double s2 = 0;
1638  double s3 = 0;
1639  // flat PDs
1640  if ((opDet.type == 0 || opDet.type == 2) && fIsFlatPDCorr) {
1641  pars_ini[0] = fGHvuvpars_flat[0][j];
1642  pars_ini[1] = fGHvuvpars_flat[1][j];
1643  pars_ini[2] = fGHvuvpars_flat[2][j];
1644  pars_ini[3] = fGHvuvpars_flat[3][j];
1648  }
1649  // dome PDs
1650  else if (opDet.type == 1 && fIsDomePDCorr) {
1651  pars_ini[0] = fGHvuvpars_dome[0][j];
1652  pars_ini[1] = fGHvuvpars_dome[1][j];
1653  pars_ini[2] = fGHvuvpars_dome[2][j];
1654  pars_ini[3] = fGHvuvpars_dome[3][j];
1658  }
1659  else
1660  std::cout << "Error: Invalid optical detector type. 0 = rectangular, 1 = dome, 2 = disk. Or "
1661  "corrections for chosen optical detector type missing."
1662  << std::endl;
1663 
1664  // add border correction
1665  pars_ini[0] = pars_ini[0] + s1 * r;
1666  pars_ini[1] = pars_ini[1] + s2 * r;
1667  pars_ini[2] = pars_ini[2] + s3 * r;
1668  pars_ini[3] = pars_ini[3];
1669 
1670  // calculate correction
1671  double GH_correction = Gaisser_Hillas(distance, pars_ini);
1672 
1673  // calculate number photons
1674  double hits_rec = GH_correction * hits_geo / cosine;
1675  int hits_vuv = std::round(G4Poisson(hits_rec));
1676 
1677  return hits_vuv;
1678  }
TRandom r
Definition: spectrum.C:23
G4double Gaisser_Hillas(const double x, const double *par) const
constexpr auto abs(T v)
Returns the absolute value of the argument.
std::vector< std::vector< double > > fGHvuvpars_flat
std::vector< std::vector< double > > fGHvuvpars_dome
unsigned int fillCoords(Coords &dest, Vector const &src)
Fills a coordinate array with the coordinates of a vector.
std::vector< double > fborder_corr_angulo_dome
std::vector< std::vector< double > > fborder_corr_dome
std::vector< std::vector< double > > fborder_corr_flat
std::vector< double > fborder_corr_angulo_flat
Float_t d
Definition: plot.C:235
double Rectangle_SolidAngle(const double a, const double b, const double d) const
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
double Omega_Dome_Model(const double distance, const double theta) const
double Disk_SolidAngle(const double d, const double h, const double b) const
double interpolate(const std::vector< double > &xData, const std::vector< double > &yData, double x, bool extrapolate, size_t i=0) const
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
double fast_acos(double x)

Member Data Documentation

bool const larg4::OpFastScintillation::bPropagate
private

Whether propagation of photons is enabled.

Definition at line 412 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and RecordPhotonsProduced().

G4EmSaturation* larg4::OpFastScintillation::emSaturation
private
G4double larg4::OpFastScintillation::ExcitationRatio
protected

Definition at line 278 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and RecordPhotonsProduced().

std::vector<geo::BoxBoundedGeo> const larg4::OpFastScintillation::fActiveVolumes
private

Definition at line 397 of file OpFastScintillation.hh.

Referenced by isScintInActiveVolume(), and OpFastScintillation().

double larg4::OpFastScintillation::fangle_bin_timing_vis
private

Definition at line 348 of file OpFastScintillation.hh.

Referenced by getVISTimes(), and OpFastScintillation().

double larg4::OpFastScintillation::fangle_bin_timing_vuv
private

Definition at line 338 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and propagationTime().

std::vector<double> larg4::OpFastScintillation::fborder_corr_angulo_dome
private

Definition at line 378 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and VUVHits().

std::vector<double> larg4::OpFastScintillation::fborder_corr_angulo_flat
private

Definition at line 373 of file OpFastScintillation.hh.

Referenced by detectedReflecHits(), OpFastScintillation(), and VUVHits().

std::vector<std::vector<double> > larg4::OpFastScintillation::fborder_corr_dome
private

Definition at line 379 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and VUVHits().

std::vector<std::vector<double> > larg4::OpFastScintillation::fborder_corr_flat
private

Definition at line 374 of file OpFastScintillation.hh.

Referenced by detectedReflecHits(), OpFastScintillation(), and VUVHits().

geo::Point_t larg4::OpFastScintillation::fcathode_centre
private
Dims larg4::OpFastScintillation::fcathode_plane
private

Definition at line 402 of file OpFastScintillation.hh.

Referenced by detectedReflecHits(), and OpFastScintillation().

double larg4::OpFastScintillation::fcathode_ydimension
private

Definition at line 395 of file OpFastScintillation.hh.

Referenced by OpFastScintillation().

double larg4::OpFastScintillation::fcathode_zdimension
private

Definition at line 395 of file OpFastScintillation.hh.

Referenced by OpFastScintillation().

std::vector<std::vector<std::vector<double> > > larg4::OpFastScintillation::fcut_off_pars
private

Definition at line 351 of file OpFastScintillation.hh.

Referenced by getVISTimes(), and OpFastScintillation().

double larg4::OpFastScintillation::fdelta_angulo_vis
private

Definition at line 384 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and VISHits().

double larg4::OpFastScintillation::fdelta_angulo_vuv
private

Definition at line 369 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and VUVHits().

std::vector<double> larg4::OpFastScintillation::fdistances_refl
private

Definition at line 349 of file OpFastScintillation.hh.

Referenced by getVISTimes(), and OpFastScintillation().

G4bool larg4::OpFastScintillation::fFiniteRiseTime
protected

Definition at line 274 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and RecordPhotonsProduced().

std::vector<std::vector<double> > larg4::OpFastScintillation::fGHvuvpars_dome
private

Definition at line 377 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and VUVHits().

std::vector<std::vector<double> > larg4::OpFastScintillation::fGHvuvpars_flat
private

Definition at line 372 of file OpFastScintillation.hh.

Referenced by detectedReflecHits(), OpFastScintillation(), and VUVHits().

double larg4::OpFastScintillation::finflexion_point_distance
private

Definition at line 338 of file OpFastScintillation.hh.

Referenced by generateParam(), and OpFastScintillation().

bool larg4::OpFastScintillation::fIsDomePDCorr
private

Definition at line 376 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), VISHits(), and VUVHits().

bool larg4::OpFastScintillation::fIsFlatPDCorr
private

Definition at line 371 of file OpFastScintillation.hh.

Referenced by detectedReflecHits(), OpFastScintillation(), VISHits(), and VUVHits().

int larg4::OpFastScintillation::fL_abs_vuv
private

Definition at line 403 of file OpFastScintillation.hh.

Referenced by detectedReflecHits(), OpFastScintillation(), and VUVHits().

double larg4::OpFastScintillation::fmax_d
private

Definition at line 338 of file OpFastScintillation.hh.

Referenced by OpFastScintillation().

double larg4::OpFastScintillation::fmin_d
private
bool const larg4::OpFastScintillation::fOnlyActiveVolume = false
private

Whether photon propagation is performed only from active volumes.

Definition at line 420 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and RecordPhotonsProduced().

bool const larg4::OpFastScintillation::fOnlyOneCryostat = false
private

Allows running even if light on cryostats C:1 and higher is not supported. Currently hard coded "no"

Definition at line 423 of file OpFastScintillation.hh.

Referenced by OpFastScintillation().

bool const larg4::OpFastScintillation::fOpaqueCathode = false
private

Whether the cathodes are fully opaque; currently hard coded "no".

Definition at line 425 of file OpFastScintillation.hh.

Referenced by RecordPhotonsProduced().

std::vector<geo::Point_t> larg4::OpFastScintillation::fOpDetCenter
private
std::vector<double> larg4::OpFastScintillation::fOpDetHeight
private
std::vector<double> larg4::OpFastScintillation::fOpDetLength
private
std::vector<int> larg4::OpFastScintillation::fOpDetType
private
std::vector<std::vector<double> > larg4::OpFastScintillation::fparameters[7]
private

Definition at line 340 of file OpFastScintillation.hh.

Referenced by generateParam(), and OpFastScintillation().

double larg4::OpFastScintillation::fplane_depth
private
phot::PhotonVisibilityService const* const larg4::OpFastScintillation::fPVS
private

Photon visibility service instance.

Definition at line 415 of file OpFastScintillation.hh.

Referenced by detectedDirectHits(), detectedReflecHits(), OpFastScintillation(), propagationTime(), and RecordPhotonsProduced().

std::vector<double> larg4::OpFastScintillation::fradial_distances_refl
private

Definition at line 350 of file OpFastScintillation.hh.

Referenced by getVISTimes(), and OpFastScintillation().

double larg4::OpFastScintillation::fradius
private

Definition at line 401 of file OpFastScintillation.hh.

Referenced by Omega_Dome_Model(), OpFastScintillation(), VISHits(), and VUVHits().

double larg4::OpFastScintillation::fstep_size
private
bool larg4::OpFastScintillation::fStoreReflected
private

Definition at line 382 of file OpFastScintillation.hh.

Referenced by OpFastScintillation().

std::vector<std::vector<std::vector<double> > > larg4::OpFastScintillation::ftau_pars
private

Definition at line 352 of file OpFastScintillation.hh.

Referenced by getVISTimes(), and OpFastScintillation().

std::unique_ptr<CLHEP::RandGeneral> larg4::OpFastScintillation::fTPBEm
private

Definition at line 321 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and reemission_energy().

G4bool larg4::OpFastScintillation::fTrackSecondariesFirst
protected

Definition at line 273 of file OpFastScintillation.hh.

Referenced by OpFastScintillation().

bool const larg4::OpFastScintillation::fUseNhitsModel = false
private

Whether the semi-analytic model is being used for photon visibility.

Definition at line 418 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and usesSemiAnalyticModel().

std::vector<double> larg4::OpFastScintillation::fvis_distances_r_dome
private

Definition at line 391 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and VISHits().

std::vector<double> larg4::OpFastScintillation::fvis_distances_r_flat
private

Definition at line 387 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and VISHits().

std::vector<double> larg4::OpFastScintillation::fvis_distances_x_dome
private

Definition at line 390 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and VISHits().

std::vector<double> larg4::OpFastScintillation::fvis_distances_x_flat
private

Definition at line 386 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and VISHits().

double larg4::OpFastScintillation::fvis_vmean
private

Definition at line 348 of file OpFastScintillation.hh.

Referenced by getVISTimes(), and OpFastScintillation().

std::vector<std::vector<std::vector<double> > > larg4::OpFastScintillation::fvispars_dome
private

Definition at line 392 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and VISHits().

std::vector<std::vector<std::vector<double> > > larg4::OpFastScintillation::fvispars_flat
private

Definition at line 388 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and VISHits().

double larg4::OpFastScintillation::fvuv_vgroup_max
private

Definition at line 338 of file OpFastScintillation.hh.

Referenced by generateParam(), getVISTimes(), and OpFastScintillation().

double larg4::OpFastScintillation::fvuv_vgroup_mean
private

Definition at line 338 of file OpFastScintillation.hh.

Referenced by generateParam(), getVUVTimes(), and OpFastScintillation().

phot::MappedFunctions_t larg4::OpFastScintillation::ParPropTimeTF1
private

Definition at line 327 of file OpFastScintillation.hh.

Referenced by propagationTime(), and RecordPhotonsProduced().

phot::MappedT0s_t larg4::OpFastScintillation::ReflT0s
private

Definition at line 328 of file OpFastScintillation.hh.

Referenced by RecordPhotonsProduced().

G4bool larg4::OpFastScintillation::scintillationByParticleType
protected
std::unique_ptr<G4PhysicsTable> larg4::OpFastScintillation::theFastIntegralTable
protected
std::unique_ptr<G4PhysicsTable> larg4::OpFastScintillation::theSlowIntegralTable
protected
std::map<double, double> larg4::OpFastScintillation::tpbemission
private

Definition at line 320 of file OpFastScintillation.hh.

Referenced by OpFastScintillation(), and reemission_energy().

std::vector<std::vector<double> > larg4::OpFastScintillation::VUV_max
private

Definition at line 344 of file OpFastScintillation.hh.

Referenced by generateParam(), getVUVTimes(), and OpFastScintillation().

std::vector<std::vector<double> > larg4::OpFastScintillation::VUV_min
private
std::vector<std::vector<TF1> > larg4::OpFastScintillation::VUV_timing
private

Definition at line 342 of file OpFastScintillation.hh.

Referenced by generateParam(), getVUVTimes(), and OpFastScintillation().

G4double larg4::OpFastScintillation::YieldFactor
protected

Definition at line 276 of file OpFastScintillation.hh.

Referenced by OpFastScintillation().


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