G4StationSimulator/G4TankPMTAction.cc
Go to the documentation of this file.
1 #include "G4TankPMTAction.h"
2 #include "G4StationEventAction.h"
3 #include "G4StationSimulator.h"
5 
6 #include <sevt/PMT.h>
7 #include <sevt/PMTSimData.h>
8 #include <sevt/SEvent.h>
9 #include <sevt/Station.h>
10 #include <sevt/StationSimData.h>
11 
12 #include <det/Detector.h>
13 #include <sdet/SDetector.h>
14 
15 #include <utl/ErrorLogger.h>
16 #include <utl/Particle.h>
17 #include <utl/ParticleCases.h>
18 #include <utl/Trace.h>
19 
20 
21 #include <fwk/RandomEngineRegistry.h>
22 #include <fwk/RunController.h>
23 
24 #include <G4Event.hh>
25 #include <G4HCofThisEvent.hh>
26 #include <G4SDManager.hh>
27 #include <G4Step.hh>
28 #include <G4TouchableHistory.hh>
29 #include <G4Track.hh>
30 #include <G4Trajectory.hh>
31 #include <G4TrajectoryContainer.hh>
32 #include <G4VHitsCollection.hh>
33 
34 #include <iostream>
35 
36 using namespace std;
37 using namespace sevt;
38 using namespace sdet;
39 using namespace det;
40 using namespace utl;
41 using namespace fwk;
42 
43 
44 namespace G4StationSimulatorOG {
45 
46  G4TankPMTAction::G4TankPMTAction(const G4String& name, const int pmtIndex) :
47  G4VSensitiveDetector(name),
48  fPMTIndex(pmtIndex),
49  fG4StationSimulator(
50  dynamic_cast<G4StationSimulator&>(RunController::GetInstance().GetModule("G4StationSimulatorOG"))
51  )
52  {
53  if (pmtIndex < 1 || pmtIndex > 5) {
54  FATAL("G4PMTAction() : invalid PMT index.");
55  exit(EXIT_FAILURE);
56  }
57  }
58 
59 
60  G4bool
61  G4TankPMTAction::ProcessHits(G4Step* const step, G4TouchableHistory* const /*rOHist*/)
62  {
63  // use to reject hits registered in sensitive volume in case the particle is not a photon
65  if (particle)
66  return true; // kill
67 
68  const double time = step->GetPreStepPoint()->GetGlobalTime() * (utl::second / CLHEP::second);
69  if (time >= 1*CLHEP::second)
70  return true; // kill
71 
72  // sometimes particles (PDG ID=0, photons?) with crazy energy
73  const double energy = step->GetPreStepPoint()->GetKineticEnergy() * (utl::MeV / CLHEP::MeV);
74 
76  const auto& dStation = G4StationSimulator::fgCurrent.GetDetectorStation();
77 
78  if (station.GetSimData().GetSimulatorSignature() == "G4StationSimulatorFullTrackOG") {
79 
80  // if SimulatorSignature is G4StationSimulatorFullTrackOG randomly kill
81  // photons with correct quntum and collection efficiency for each PMT type
82 
83  const auto& pmt = dStation.GetPMT(fPMTIndex);
84  const auto& qeff = pmt.GetQuantumEfficiency();
85  if (energy < qeff.XFront() || energy > qeff.XBack())
86  return true; // kill
87 
88  const double eff = pmt.GetCollectionEfficiency() * qeff.InterpolateY(energy, 1);
89  const auto rand = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector).GetEngine();
90  if (CLHEP::RandFlat::shoot(rand, 0, 1) > eff)
91  return true; // kill
92 
93  } else {
94 
95  // if not random killing is done already in StationStackingAction.cc to
96  // speed up simulation (standard way); here only the difference between
97  // the maximal efficiency envelope and the individual PMTs is considered
98 
99  if (dStation.HasSmallPMT()) {
100 
101  const auto& pmt = dStation.GetPMT(fPMTIndex);
102  const auto& qeff = pmt.GetQuantumEfficiency();
103  if (energy < qeff.XFront() || energy > qeff.XBack())
104  return true; // kill
105  const double eff = pmt.GetCollectionEfficiency() * qeff.InterpolateY(energy, 1);
106 
107  const auto& pmtLarge = dStation.GetPMT(1);
108  const double effLarge =
109  pmtLarge.GetCollectionEfficiency() * pmtLarge.GetQuantumEfficiency().InterpolateY(energy, 1);
110  const auto& pmtSmall = dStation.GetPMT(4);
111  const double effSmall =
112  pmtSmall.GetCollectionEfficiency() * pmtSmall.GetQuantumEfficiency().InterpolateY(energy, 1);
113  const double effMax = std::max(effSmall, effLarge);
114  if (effMax < 1e-5)
115  return true; // kill
116 
117  const auto rand = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector).GetEngine();
118  if (effMax * CLHEP::RandFlat::shoot(rand, 0, 1) > eff)
119  return true; // kill
120  }
121 
122  }
123 
124  fG4StationSimulator.AddPhoton(fPMTIndex, time); // count the photon
125  // note that in the current simplified simulation, the photons hitting the pmt are always absorbed:
126  return true; // kill
127  }
128 
129 }
constexpr double second
Definition: AugerUnits.h:145
void AddPhoton(const int nPMT, const double peTime) const
peTime in Auger units!
#define FATAL(message)
Macro for logging fatal messages.
Definition: ErrorLogger.h:167
const PMT & GetPMT(const int id) const
Get specified PMT by id.
int exit
Definition: dump1090.h:237
constexpr double MeV
Definition: AugerUnits.h:184
#define max(a, b)
const double second
Definition: GalacticUnits.h:32
Auger Software Run Control.
Definition: RunController.h:26
double InterpolateY(const double x, const unsigned int polyDegree) const
Interpolate the Y value with a polyDegree polynomial.
class that handles Geant4 SD Station simulation adopted from G4TankSimulator
const utl::TabulatedFunction & GetQuantumEfficiency() const
Quantum efficiency.
struct particle_info particle[80]
G4bool ProcessHits(G4Step *const step, G4TouchableHistory *const rOHist) override

, generated on Tue Sep 26 2023.