G4ASCIIAction.cc
Go to the documentation of this file.
1 #include "G4ASCIIAction.h"
2 #include "G4TankEventAction.h"
3 #include "G4TankSimulator.h"
4 #include "G4TankSteppingAction.h"
5 #include "G4TankTrackingAction.h"
7 #include "ParticleCases.h"
8 
9 #include <sevt/PMT.h>
10 #include <sevt/PMTConstants.h>
11 #include <sevt/PMTSimData.h>
12 #include <sevt/SEvent.h>
13 #include <sevt/Station.h>
14 #include <sevt/StationSimData.h>
15 
16 #include <utl/ErrorLogger.h>
17 #include <utl/Particle.h>
18 #include <utl/Trace.h>
19 #include <utl/PhysicalConstants.h>
20 
21 #include <fwk/RandomEngineRegistry.h>
22 #include <CLHEP/Random/RandFlat.h>
23 #include <CLHEP/Random/RandPoisson.h>
24 #include <CLHEP/Random/RandExponential.h>
25 #include <fwk/RunController.h>
26 
27 #include <G4Event.hh>
28 #include <G4HCofThisEvent.hh>
29 #include <G4SDManager.hh>
30 #include <G4Step.hh>
31 #include <G4TouchableHistory.hh>
32 #include <G4Track.hh>
33 #include <G4Trajectory.hh>
34 #include <G4TrajectoryContainer.hh>
35 #include <G4VHitsCollection.hh>
36 
37 #include <iostream>
38 
39 using namespace std;
40 using namespace G4TankSimulatorASCII;
41 using namespace sevt;
42 using namespace utl;
43 using namespace fwk;
44 
45 
46 using CLHEP::RandFlat;
47 using CLHEP::RandPoisson;
48 using CLHEP::RandExponential;
49 
50 
51 
52 G4ASCIIAction::G4ASCIIAction(const G4String name) :
53  G4VSensitiveDetector(name)
54 {
55 
57  dynamic_cast<G4TankSimulator*>(&RunController::GetInstance().GetModule("G4TankSimulatorASCII"));
58 
60  &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector);
61 }
62 
63 
64 G4bool
65 G4ASCIIAction::ProcessHits(G4Step* theStep, G4TouchableHistory* /*R0Hist*/)
66 {
67  // Fill ASCII : use PMT4 to save the single photoelectron distribution
68 
69  if ( theStep->GetTrack()->GetDefinition()->GetPDGCharge() == 0 ) return true;
70 
71  if ( theStep->GetTrack()->GetVolume()->GetName() !="scin" )
72  {
73 
74  return true;
75  }
76 
77  const bool IsFromMuonDecay=theStep->GetTrack()->GetUserInformation();
78  unsigned int fBarIndex=theStep->GetTrack()->GetVolume()->GetCopyNo();
79  const unsigned int fPMTIndex=5; // Temporary.
80  const double time = theStep->GetPreStepPoint()->GetGlobalTime();
81  const double Edep=theStep->GetTotalEnergyDeposit();
82  const double xPos=theStep->GetTrack()->GetPosition().x();
83  if ( Edep <=0. ) return true;
84 
85  const int currentParticle = G4TankSteppingAction::GetCurrentParticleId();
86 
87  if (time >= 1*utl::second )
88  return true;
89 
90  //---------------------------------------------------------------------------
91 
92 
93  if ( theStep->GetTrack()->GetTrackID() ==1 )
94  {
95  G4TankTrackingAction::ASCII_Track_p += (theStep->GetStepLength());
97  }
98 
99  G4TankTrackingAction::ASCII_Track += (theStep->GetStepLength());
102  if ( IsFromMuonDecay ) G4TankTrackingAction::ASCII_Edep_Michel += (Edep);
103 
104  //---------------------------------------------------------------------------
105 
110 
111  if (!station.HasPMT(fPMTIndex)) {
112  // if the station doesn't have a scintillator PMT, no PE traces can be stored
113  return true;
114  }
115 
116  if (!station.GetPMT(fPMTIndex).HasSimData())
117  station.GetPMT(fPMTIndex).MakeSimData();
118 
119  PMTSimData& pmtSim = station.GetPMT(fPMTIndex).GetSimData();
120 
121  ostringstream msg;
122 
123  switch (particle) {
124  case OFFLINE_PHOTON:
126  break;
127  case OFFLINE_ELECTRONS:
129  break;
130  case OFFLINE_MUONS:
131  component = sevt::StationConstants::eMuon;
132  break;
133  default:
135  break;
136  }
137 
138  if (!pmtSim.HasPETimeDistribution(totcomponent)) pmtSim.MakePETimeDistribution(totcomponent);
139  if (!pmtSim.HasPETimeDistribution(component)) pmtSim.MakePETimeDistribution(component);
140 
141  TimeDistributionI &totalDist = pmtSim.GetPETimeDistribution(totcomponent);
142  TimeDistributionI &compDist = pmtSim.GetPETimeDistribution(component);
143 
144  const double attenuationLength=308.*CLHEP::cm,attenuationAmplitude=24.4;
145  const double attenuationReferenceEnergy=2.25*CLHEP::MeV;
146 
147 
148  double X=xPos+900.*CLHEP::mm+20.*CLHEP::cm; // X from the PMT
149  double lambda=attenuationAmplitude*exp(-X/attenuationLength);
150 
151  double nPe_mean=lambda*Edep/attenuationReferenceEnergy;
152  unsigned int nPe=RandPoisson::shoot(&fRandomEngine->GetEngine(), nPe_mean);
153 
154  const double refractionIndex=1.42;
155  const double decayTime[2]={ 3.7, 3.5 } ;// fiber/scin [ns]
156  const double pathDelay = (xPos/CLHEP::m) * refractionIndex/ utl::kSpeedOfLight;
157 
158 
159  // Loop over SPE
160  for (unsigned int ipe=0;ipe<nPe;ipe++)
161  {
162  double delay=pathDelay;
163  const double fiberDelay = RandExponential::shoot(&fRandomEngine->GetEngine(), decayTime[0]);
164  const double scintDelay = RandExponential::shoot(&fRandomEngine->GetEngine(), decayTime[1]);
165  delay += ( fiberDelay+scintDelay);
166 
167  totalDist.AddTime(time+delay);
168  compDist.AddTime(time+delay);
169  if ( IsFromMuonDecay )
170  {
173  }
174  }
175 
176  return true;
177 
178 }
179 
constexpr double second
Definition: AugerUnits.h:145
bool HasPMT(const unsigned int pmtId) const
Check if a particular PMT object exists.
constexpr double mm
Definition: AugerUnits.h:113
PMTSimData & GetSimData()
Get object containing PMT simulated data.
Definition: SEvent/PMT.h:40
total (shower and background)
RandomEngineType & GetEngine()
Definition: RandomEngine.h:32
bool compDist(antenna i, antenna j)
Definition: tabulatedata.cc:52
Histogram class for time distributions with suppressed empty bins.
bool HasPETimeDistribution(const StationConstants::SignalComponent source=StationConstants::eTotal) const
Check if a PE release time distribution exists (optionally for a given source)
Definition: PMTSimData.h:65
void MakeSimData()
Make PMT simulated data object.
Definition: SEvent/PMT.cc:19
constexpr double MeV
Definition: AugerUnits.h:184
electrons and positrons from shower
class to hold data at Station level
static int delay
Definition: XbAlgo.cc:20
bool HasSimData() const
Check for existence of PMT simulated data object.
Definition: SEvent/PMT.h:45
constexpr double kSpeedOfLight
PMT & GetPMT(const unsigned int pmtId)
Retrive a PMT by Id.
Class to hold simulated data at PMT level.
Definition: PMTSimData.h:40
constexpr double cm
Definition: AugerUnits.h:117
struct particle_info particle[80]
utl::TimeDistributionI & GetPETimeDistribution(const StationConstants::SignalComponent source=StationConstants::eTotal)
Simulated photoelectron time distribution.
Definition: PMTSimData.h:54
constexpr double m
Definition: AugerUnits.h:121
void AddTime(const double time, const T weight=T(1))
Add an entry (optionally weighted) for the given time. Slot will be computed.
mu+ and mu- (including signal from mu decay electrons) from shower
void MakePETimeDistribution(const StationConstants::SignalComponent source=StationConstants::eTotal)
Create a PE release time distribution (optionally for given source)
Definition: PMTSimData.cc:12
G4bool ProcessHits(G4Step *theStep, G4TouchableHistory *R0Hist)

, generated on Tue Sep 26 2023.