G4ScintillatorAction.cc
Go to the documentation of this file.
1 #include "G4ScintillatorAction.h"
2 #include "G4StationEventAction.h"
3 #include "G4StationSimulator.h"
6 #include "G4Utils.h"
7 
8 #include <utl/ErrorLogger.h>
9 #include <utl/RandomEngine.h>
10 
11 #include <fwk/RandomEngineRegistry.h>
12 #include <fwk/RunController.h>
13 
14 #include <G4Event.hh>
15 #include <G4HCofThisEvent.hh>
16 #include <G4SDManager.hh>
17 #include <G4Step.hh>
18 #include <G4TouchableHistory.hh>
19 #include <G4Track.hh>
20 #include <G4Trajectory.hh>
21 #include <G4TrajectoryContainer.hh>
22 #include <G4VHitsCollection.hh>
23 
24 #include <CLHEP/Random/RandPoisson.h>
25 #include <CLHEP/Random/RandExponential.h>
26 
27 #include <utl/AugerUnits.h>
28 #include <utl/PhysicalConstants.h>
29 #include <G4SystemOfUnits.hh>
30 #include <G4ThreeVector.hh>
31 
32 #include <iostream>
33 #include <fstream>
34 
35 using namespace fwk;
36 using namespace std;
37 
38 using CLHEP::RandPoisson;
39 using CLHEP::RandExponential;
40 
41 
42 namespace G4StationSimulatorOG {
43 
44  G4ScintillatorAction::G4ScintillatorAction(const G4String& name) :
45  G4VSensitiveDetector(name),
46  fG4StationSimulator(
47  dynamic_cast<G4StationSimulator&>(RunController::GetInstance().GetModule("G4StationSimulatorOG"))
48  )
49  { }
50 
51 
52  G4bool
53  G4ScintillatorAction::ProcessHits(G4Step* const step, G4TouchableHistory* const /*rOHist*/)
54  {
55  // this code uses Offline units, converted only when passed to G4
56 
57  const double eDep = step->GetTotalEnergyDeposit() * (utl::eV / CLHEP::eV);
58 
59  // if no energy is deposited, no photons (and thus no photoelectrons) will be produced
60  if (!eDep)
61  return true; // drop
62 
64 
65  /* Unfortunately at the time of writing this comment, the geant detector volumes are only
66  * constructed once and re-used for the simulation of different stations. Because of this, it is
67  * possible for scintillator volumes to exist in the geant world volume above the water-cherenkov
68  * detector even if the station in question does not have a scintillator (meaning there is no
69  * sdet/sevt Scintillator). If the detector volumes were to be properly updated between the
70  * simulation of each station with Geant, the check below would be unnecessary and could be
71  * removed. */
72  if (!dStation.HasScintillator())
73  return true; // drop
74 
75  const double time = step->GetPreStepPoint()->GetGlobalTime() * (utl::ns / CLHEP::ns);
76 
77  // The coordinate system of the Geant4 world volume is identical to the Station coordinate system.
79 
80  const utl::Point position = To<utl::Point>(step->GetTrack()->GetPosition(), cs, utl::meter/CLHEP::meter);
81 
82  const sdet::Scintillator& scin = dStation.GetScintillator();
83 
84  // number of PEs for a given reference energy
85  const double refPENumber = scin.GetReferencePENumber();
86  const double refEnergy = scin.GetReferenceEnergy();
87 
88  // fiber attenuation length and parameters describing photon leakage at bar ends
89  const double attLength = scin.GetAttenuationLength();
90  const double barLeakExpCoeff = scin.GetBarLeakageExpCoefficient();
91  const double barLeakMaxRatio = scin.GetBarLeakageMaxRatio();
92 
93  // properties governing PE arrival time distribution
94  const double effRefractiveIndex = scin.GetEffectiveRefractiveIndex();
95  const double fiberExpDecayConst = scin.GetFiberExpDecayConstant();
96  const double barExpDecayConst = scin.GetBarExpDecayConstant();
97 
98  // distances from point of traversal to PMT along fiber
99  const std::vector<double>& fiberDistances = scin.GetDistancesToPMT(position);
100  // distances to both ends of the bar traversed (first element is end closer to PMT)
101  const std::pair<double, double>& barDistances = scin.GetDistancesToBarEnds(position);
102 
103  // for both legs of signal
104  for (double d : fiberDistances) {
105  // attenuation along fiber for distance to PMT
106  const double att = exp(-d / attLength);
107  // photon loss at end of bar closer to PMT
108  const double leakInner = 1 - barLeakMaxRatio * exp(-barDistances.first / barLeakExpCoeff);
109  // photon loss at end of bar further from PMT
110  const double leakOuter = 1 - barLeakMaxRatio * exp(-barDistances.second / barLeakExpCoeff);
111 
112  const double npeMean = 0.5 * eDep / refEnergy * refPENumber * att * leakInner * leakOuter;
113  const auto rand = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector).GetEngine();
114  const unsigned int npe = CLHEP::RandPoisson::shoot(rand, npeMean);
115  for (unsigned int i = 0; i < npe; ++i) {
116  const double scinDelay = CLHEP::RandExponential::shoot(rand, barExpDecayConst);
117  const double fiberDelay = CLHEP::RandExponential::shoot(rand, fiberExpDecayConst);
118  const double pathDelay = d * effRefractiveIndex / utl::kSpeedOfLight;
119  const double peTime = time + scinDelay + fiberDelay + pathDelay;
120  // needs to be a better way than hardcoding scint PMT id while maintaining flexibility,
121  // but static constants for ids in sdet station are private (and should stay that way)
122  fG4StationSimulator.AddPhoton(5, peTime); // keep
123  }
124  }
125 
126  return true;
127  }
128 
129 }
void AddPhoton(const int nPMT, const double peTime) const
peTime in Auger units!
const double eV
Definition: GalacticUnits.h:35
constexpr double eV
Definition: AugerUnits.h:185
Point object.
Definition: Point.h:32
Detector description interface for Station-related data.
const double meter
Definition: GalacticUnits.h:29
virtual G4bool ProcessHits(G4Step *const step, G4TouchableHistory *const rOHist) override
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
const double ns
constexpr double meter
Definition: AugerUnits.h:81
Auger Software Run Control.
Definition: RunController.h:26
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
Get the Auger reference system centered on the tank.
const Scintillator & GetScintillator() const
constexpr double kSpeedOfLight
double GetReferencePENumber() const
class that handles Geant4 SD Station simulation adopted from G4TankSimulator
bool HasScintillator() const
constexpr double ns
Definition: AugerUnits.h:162

, generated on Tue Sep 26 2023.