98 #include "TLorentzVector.h" 100 #include "Geant4/globals.hh" 101 #include "Geant4/G4ParticleTypes.hh" 102 #include "Geant4/G4EmProcessSubType.hh" 103 #include "Geant4/Randomize.hh" 104 #include "Geant4/G4Poisson.hh" 105 #include "Geant4/G4VPhysicalVolume.hh" 127 #include "cetlib_except/exception.h" 129 #include "TRandom3.h" 131 #include "boost/algorithm/string.hpp" 152 : G4VRestDiscreteProcess(processName, type)
153 , bPropagate(!(
art::ServiceHandle<
sim::LArG4Parameters>()->NoPhotonPropagation()))
155 G4cout<<
"BEA1 timing distribution"<<G4endl;
156 SetProcessSubType(25);
172 if (verboseLevel>0) {
173 G4cout << GetProcessName() <<
" is created " << G4endl;
188 tpbemission=lar::providerFrom<detinfo::LArPropertiesService>()->TpbEm();
190 double * parent=
new double[nbins];
194 parent[ii++]=(*iter).second;
196 rgen0 =
new CLHEP::RandGeneral(parent,nbins);
203 : G4VRestDiscreteProcess(rhs.GetProcessName(), rhs.GetProcessType())
264 aParticleChange.Initialize(aTrack);
268 const G4Material* aMaterial = aTrack.GetMaterial();
269 G4MaterialPropertiesTable* aMaterialPropertiesTable =
270 aMaterial->GetMaterialPropertiesTable();
271 if (!aMaterialPropertiesTable)
272 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
274 G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint();
276 G4ThreeVector x0 = pPreStepPoint->GetPosition();
277 G4ThreeVector p0 = aStep.GetDeltaPosition().unit();
328 aParticleChange.SetNumberOfSecondaries(0);
356 if (verboseLevel>0) {
357 G4cout <<
"\n Exiting from OpFastScintillation::DoIt -- NumberOfSecondaries = " 358 << aParticleChange.GetNumberOfSecondaries() << G4endl;
362 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
369 if(step.GetTotalEnergyDeposit() <= 0)
return;
374 (
double)(step.GetTotalEnergyDeposit()/CLHEP::MeV),
375 (
float)(step.GetPreStepPoint()->GetPosition().x()/CLHEP::cm),
376 (
float)(step.GetPreStepPoint()->GetPosition().y()/CLHEP::cm),
377 (
float)(step.GetPreStepPoint()->GetPosition().z()/CLHEP::cm),
378 (
float)(step.GetPostStepPoint()->GetPosition().x()/CLHEP::cm),
379 (
float)(step.GetPostStepPoint()->GetPosition().y()/CLHEP::cm),
380 (
float)(step.GetPostStepPoint()->GetPosition().z()/CLHEP::cm),
381 (
double)(step.GetPreStepPoint()->GetGlobalTime()),
382 (
double)(step.GetPostStepPoint()->GetGlobalTime()),
385 step.GetTrack()->GetParticleDefinition()->GetPDGEncoding(),
386 step.GetPreStepPoint()->GetPhysicalVolume()->GetName()
403 const G4Track * aTrack = aStep.GetTrack();
405 G4StepPoint
const* pPreStepPoint = aStep.GetPreStepPoint();
408 const G4DynamicParticle* aParticle = aTrack->GetDynamicParticle();
409 const G4Material* aMaterial = aTrack->GetMaterial();
411 G4int materialIndex = aMaterial->GetIndex();
412 G4int tracknumber = aStep.GetTrack()->GetTrackID();
414 G4ThreeVector x0 = pPreStepPoint->GetPosition();
415 G4ThreeVector p0 = aStep.GetDeltaPosition().unit();
417 G4double
t0 = pPreStepPoint->GetGlobalTime();
420 G4MaterialPropertiesTable* aMaterialPropertiesTable =
421 aMaterial->GetMaterialPropertiesTable();
423 G4MaterialPropertyVector* Fast_Intensity =
424 aMaterialPropertiesTable->GetProperty(
"FASTCOMPONENT");
425 G4MaterialPropertyVector* Slow_Intensity =
426 aMaterialPropertiesTable->GetProperty(
"SLOWCOMPONENT");
428 if (!Fast_Intensity && !Slow_Intensity )
440 if (Fast_Intensity && Slow_Intensity) nscnt = 2;
452 G4ParticleDefinition *pDef = aParticle->GetDefinition();
459 if(pDef==G4Proton::ProtonDefinition())
461 YieldRatio = aMaterialPropertiesTable->
462 GetConstProperty(
"PROTONYIELDRATIO");
467 else if(pDef==G4MuonPlus::MuonPlusDefinition()||pDef==G4MuonMinus::MuonMinusDefinition())
469 YieldRatio = aMaterialPropertiesTable->
470 GetConstProperty(
"MUONYIELDRATIO");
474 else if(pDef==G4PionPlus::PionPlusDefinition()||pDef==G4PionMinus::PionMinusDefinition())
476 YieldRatio = aMaterialPropertiesTable->
477 GetConstProperty(
"PIONYIELDRATIO");
481 else if(pDef==G4KaonPlus::KaonPlusDefinition()||pDef==G4KaonMinus::KaonMinusDefinition())
483 YieldRatio = aMaterialPropertiesTable->
484 GetConstProperty(
"KAONYIELDRATIO");
488 else if(pDef==G4Alpha::AlphaDefinition())
490 YieldRatio = aMaterialPropertiesTable->
491 GetConstProperty(
"ALPHAYIELDRATIO");
496 else if(pDef==G4Electron::ElectronDefinition() ||
497 pDef==G4Gamma::GammaDefinition())
499 YieldRatio = aMaterialPropertiesTable->
500 GetConstProperty(
"ELECTRONYIELDRATIO");
506 YieldRatio = aMaterialPropertiesTable->
507 GetConstProperty(
"ELECTRONYIELDRATIO");
516 YieldRatio = aMaterialPropertiesTable->
517 GetConstProperty(
"ELECTRONYIELDRATIO");
523 double const xyz[3] = { x0[0]/CLHEP::cm, x0[1]/CLHEP::cm, x0[2]/CLHEP::cm };
526 float const* ReflVisibilities =
nullptr;
566 for (G4int scnt = 1; scnt <= nscnt; scnt++) {
568 G4double ScintillationTime = 0.*CLHEP::ns;
569 G4double ScintillationRiseTime = 0.*CLHEP::ns;
570 G4PhysicsOrderedFreeVector* ScintillationIntegral = NULL;
575 ScintillationTime = aMaterialPropertiesTable->
576 GetConstProperty(
"FASTTIMECONSTANT");
578 ScintillationRiseTime = aMaterialPropertiesTable->
579 GetConstProperty(
"FASTSCINTILLATIONRISETIME");
581 ScintillationIntegral =
585 ScintillationTime = aMaterialPropertiesTable->
586 GetConstProperty(
"SLOWTIMECONSTANT");
588 ScintillationRiseTime = aMaterialPropertiesTable->
589 GetConstProperty(
"SLOWSCINTILLATIONRISETIME");
591 ScintillationIntegral =
597 YieldRatio = aMaterialPropertiesTable->
598 GetConstProperty(
"YIELDRATIO");
602 Num =
std::min(YieldRatio,1.0)*MeanNumberOfPhotons;
607 ScintillationTime = aMaterialPropertiesTable->
608 GetConstProperty(
"FASTTIMECONSTANT");
610 ScintillationRiseTime = aMaterialPropertiesTable->
611 GetConstProperty(
"FASTSCINTILLATIONRISETIME");
613 ScintillationIntegral =
619 Num = MeanNumberOfPhotons - Num;
620 ScintillationTime = aMaterialPropertiesTable->
621 GetConstProperty(
"SLOWTIMECONSTANT");
623 ScintillationRiseTime = aMaterialPropertiesTable->
624 GetConstProperty(
"SLOWSCINTILLATIONRISETIME");
626 ScintillationIntegral =
630 if (!ScintillationIntegral)
continue;
651 std::map<int, int> DetectedNum;
653 std::map<int, int> ReflDetectedNum;
655 for(
size_t OpDet=0; OpDet!=NOpChannels; OpDet++)
657 G4int DetThisPMT = G4int(G4Poisson(Visibilities[OpDet] * Num));
661 DetectedNum[OpDet]=DetThisPMT;
668 G4int ReflDetThisPMT = G4int(G4Poisson(ReflVisibilities[OpDet] * Num));
671 ReflDetectedNum[OpDet]=ReflDetThisPMT;
679 for (
int Reflected = 0; Reflected <= 1; Reflected++) {
687 itstart = ReflDetectedNum.begin();
688 itend = ReflDetectedNum.end();
691 itstart = DetectedNum.begin();
692 itend = DetectedNum.end();
697 int OpChannel = itdetphot->first;
698 int NPhotons = itdetphot->second;
708 std::vector<double> arrival_time_dist =
propagation_time(x0, OpChannel, NPhotons, Reflected);
711 for (G4int i = 0; i < NPhotons; ++i)
714 +
scint_time(aStep, ScintillationTime, ScintillationRiseTime)
715 + arrival_time_dist[i]*CLHEP::ns;
723 fst->
AddLitePhoton(OpChannel, static_cast<int>(Time), 1, Reflected);
727 TVector3 PhotonPosition( x0[0], x0[1], x0[2] );
729 float PhotonEnergy = 0;
731 else PhotonEnergy = 9.7*CLHEP::eV;
736 PhotToAdd.
Energy = PhotonEnergy;
737 PhotToAdd.
Time = Time;
741 fst->
AddPhoton(OpChannel, std::move(PhotToAdd), Reflected);
763 const G4MaterialTable* theMaterialTable =
764 G4Material::GetMaterialTable();
765 G4int numOfMaterials = G4Material::GetNumberOfMaterials();
774 for (G4int i=0 ; i < numOfMaterials; i++)
776 G4PhysicsOrderedFreeVector* aPhysicsOrderedFreeVector =
777 new G4PhysicsOrderedFreeVector();
778 G4PhysicsOrderedFreeVector* bPhysicsOrderedFreeVector =
779 new G4PhysicsOrderedFreeVector();
784 G4Material* aMaterial = (*theMaterialTable)[i];
786 G4MaterialPropertiesTable* aMaterialPropertiesTable =
787 aMaterial->GetMaterialPropertiesTable();
789 if (aMaterialPropertiesTable) {
791 G4MaterialPropertyVector* theFastLightVector =
792 aMaterialPropertiesTable->GetProperty(
"FASTCOMPONENT");
794 if (theFastLightVector) {
799 G4double currentIN = (*theFastLightVector)[0];
801 if (currentIN >= 0.0) {
806 G4double currentPM = theFastLightVector->Energy(0);
808 G4double currentCII = 0.0;
810 aPhysicsOrderedFreeVector->
811 InsertValues(currentPM , currentCII);
815 G4double prevPM = currentPM;
816 G4double prevCII = currentCII;
817 G4double prevIN = currentIN;
823 i < theFastLightVector->GetVectorLength();
826 currentPM = theFastLightVector->Energy(i);
827 currentIN = (*theFastLightVector)[i];
829 currentCII = 0.5 * (prevIN + currentIN);
831 currentCII = prevCII +
832 (currentPM - prevPM) * currentCII;
834 aPhysicsOrderedFreeVector->
835 InsertValues(currentPM, currentCII);
838 prevCII = currentCII;
845 G4MaterialPropertyVector* theSlowLightVector =
846 aMaterialPropertiesTable->GetProperty(
"SLOWCOMPONENT");
848 if (theSlowLightVector) {
853 G4double currentIN = (*theSlowLightVector)[0];
855 if (currentIN >= 0.0) {
860 G4double currentPM = theSlowLightVector->Energy(0);
862 G4double currentCII = 0.0;
864 bPhysicsOrderedFreeVector->
865 InsertValues(currentPM , currentCII);
869 G4double prevPM = currentPM;
870 G4double prevCII = currentCII;
871 G4double prevIN = currentIN;
877 i < theSlowLightVector->GetVectorLength();
880 currentPM = theSlowLightVector->Energy(i);
881 currentIN = (*theSlowLightVector)[i];
883 currentCII = 0.5 * (prevIN + currentIN);
885 currentCII = prevCII +
886 (currentPM - prevPM) * currentCII;
888 bPhysicsOrderedFreeVector->
889 InsertValues(currentPM, currentCII);
892 prevCII = currentCII;
916 G4Exception(
"OpFastScintillation::SetScintillationByParticleType",
"Scint02",
917 JustWarning,
"Redefinition: Birks Saturation is replaced by ScintillationByParticleType!");
929 G4ForceCondition* condition)
931 *condition = StronglyForced;
942 G4ForceCondition* condition)
951 G4double ScintillationTime,
952 G4double ScintillationRiseTime)
const 954 G4StepPoint
const* pPreStepPoint = aStep.GetPreStepPoint();
955 G4StepPoint
const* pPostStepPoint = aStep.GetPostStepPoint();
956 G4double avgVelocity = (pPreStepPoint->GetVelocity() + pPostStepPoint->GetVelocity())/2.;
958 G4double deltaTime = aStep.GetStepLength() / avgVelocity;
960 if (ScintillationRiseTime==0.0) {
961 deltaTime = deltaTime -
962 ScintillationTime * std::log( G4UniformRand() );
964 deltaTime = deltaTime +
965 sample_time(ScintillationRiseTime, ScintillationTime);
977 std::vector<double> arrival_time_dist(NPhotons, 0);
981 throw cet::exception(
"OpFastScintillation") <<
"Cannot have both propagation time models simultaneously.";
988 G4cout <<
"WARNING: Requested parameterized timing, but no function found. Not applying propagation time." << G4endl;
993 throw cet::exception(
"OpFastScintillation") <<
"No parameterized propagation time for reflected light";
995 for (
int i = 0; i < NPhotons; i++) {
1002 double OpDetCenter[3];
1004 G4ThreeVector OpDetPoint(OpDetCenter[0]*CLHEP::cm,OpDetCenter[1]*CLHEP::cm,OpDetCenter[2]*CLHEP::cm);
1006 double distance_in_cm = (x0 - OpDetPoint).
mag()/CLHEP::cm;
1007 arrival_time_dist =
GetVUVTime(distance_in_cm, NPhotons);
1010 double t0_vis_lib =
ReflT0s[OpChannel];
1015 return arrival_time_dist;
1027 G4double ran1 = G4UniformRand();
1028 G4double ran2 = G4UniformRand();
1032 G4double
d = (tau1+tau2)/tau2;
1035 G4double t = -1.0*tau2*std::log(1-ran1);
1037 if (ran2 <=
bi_exp(t,tau1,tau2)/g)
return t;
1051 CLHEP::Hep3Vector prePoint = (aStep.GetPreStepPoint())->GetPosition();
1052 CLHEP::Hep3Vector postPoint = (aStep.GetPostStepPoint())->GetPosition();
1053 xyzPos[0] = ( ( (prePoint.getX() + postPoint.getX() ) / 2.0) / CLHEP::cm );
1054 xyzPos[1] = ( ( (prePoint.getY() + postPoint.getY() ) / 2.0) / CLHEP::cm );
1055 xyzPos[2] = ( ( (prePoint.getZ() + postPoint.getZ() ) / 2.0) / CLHEP::cm );
1070 std::vector<double> arrival_time_distrb;
1071 arrival_time_distrb.clear();
1075 if(distance < 10 || distance >
fd_max) {
1076 G4cout<<
"WARNING: Parametrization of Direct Light not fully reliable"<<G4endl;
1077 G4cout<<
"Too close/far to the PMT -> set 0 VUV photons(?)!!!!!!"<<G4endl;
1078 return arrival_time_distrb;
1081 const double signal_t_range = 1000.;
1082 const double vuv_vgroup = 10.13;
1083 double t_direct = distance/vuv_vgroup;
1092 TF1 *flandau =
new TF1(
"flandau",
"[2]*TMath::Landau(x,[0],[1])",0,signal_t_range/2);
1093 flandau->SetParameters(pars_landau);
1099 TF1 *fexpo =
new TF1(
"fexpo",
"expo",0, signal_t_range/2);
1100 fexpo->SetParameters(pars_expo);
1102 TF1 *fint =
new TF1(
"fint",
finter_d,flandau->GetMaximumX(),3*t_direct,5);
1103 double parsInt[5] = {pars_landau[0], pars_landau[1], pars_landau[2], pars_expo[0], pars_expo[1]};
1104 fint->SetParameters(parsInt);
1105 double t_int = fint->GetMinimumX();
1106 double minVal = fint->Eval(t_int);
1109 G4cout<<
"WARNING: Parametrization of Direct Light discontinuous (landau + expo)!!!!!!"<<G4endl;
1112 double parsfinal[6] = {t_int, pars_landau[0], pars_landau[1], pars_landau[2], pars_expo[0], pars_expo[1]};
1113 fVUVTiming->SetParameters(parsfinal);
1116 int f_sampling = 1000;
1119 fVUVTiming->SetNpx(f_sampling);
1121 for(
int i=0; i<number_photons; i++)
1122 arrival_time_distrb.push_back(fVUVTiming->GetRandom());
1129 G4cout<<
"BEAMAUS timing distribution hecha"<<G4endl;
1130 return arrival_time_distrb;
1140 std::vector<double> arrival_time_distrb;
1141 arrival_time_distrb.clear();
1145 G4cout<<
"WARNING: Parametrization of Cathode-Only reflected Light not fully reliable"<<G4endl;
1146 G4cout<<
"Too close/far to the PMT -> set 0 Visible photons(?)!!!!!!"<<G4endl;
1147 return arrival_time_distrb;
1150 const double signal_t_range = 1000.;
1155 pars_landau[0] = -0.798934 + 1.06216*t0;
1163 TF1 *flandau =
new TF1(
"flandau",
"[2]*TMath::Landau(x,[0],[1])",0,signal_t_range/2);
1164 flandau->SetParameters(pars_landau);
1165 TF1 *fexpo =
new TF1(
"fexpo",
"expo",0, signal_t_range/2);
1166 fexpo->SetParameters(pars_expo);
1168 TF1 *fint =
new TF1(
"fint",
finter_d,flandau->GetMaximumX(),2*t0,5);
1169 double parsInt[5] = {pars_landau[0], pars_landau[1], pars_landau[2], pars_expo[0], pars_expo[1]};
1170 fint->SetParameters(parsInt);
1171 double t_int = fint->GetMinimumX();
1172 double minVal = fint->Eval(t_int);
1175 G4cout<<
"WARNING: Parametrization of Direct Light discontinuous (landau + expo)!!!!!!"<<G4endl;
1178 double parsfinal[6] = {t_int, pars_landau[0], pars_landau[1], pars_landau[2], pars_expo[0], pars_expo[1]};
1179 fVisTiming->SetParameters(parsfinal);
1182 int f_sampling = 1000;
1185 fVisTiming->SetNpx(f_sampling);
1187 for(
int i=0; i<number_photons; i++)
1188 arrival_time_distrb.push_back(fVisTiming->GetRandom());
1196 G4cout<<
"Timing distribution BEAMAUS!"<<G4endl;
1197 return arrival_time_distrb;
1202 double y1 = par[2]*TMath::Landau(x[0],par[0],par[1]);
1203 double y2 = TMath::Exp(par[3]+x[0]*par[4]);
1205 return TMath::Abs(y1 - y2);
1215 double y1 = par[3]*TMath::Landau(x[0],par[1],par[2]);
1216 double y2 = TMath::Exp(par[4]+x[0]*par[5]);
1217 if(x[0] > par[0]) y1 = 0.;
1218 if(x[0] < par[0]) y2 = 0.;
1226 double y1 = par[2]*TMath::Landau(x[0],par[0],par[1]);
1227 double y2 = par[5]*TMath::Landau(x[0],par[3],par[4]);
1229 return TMath::Abs(y1 - y2);
code to link reconstructed objects back to the MC truth information
Store parameters for running LArG4.
bool IncludePropTime() const
G4bool scintillationByParticleType
G4PhysicsTable * GetSlowIntegralTable() const
G4EmSaturation * GetSaturation() const
OpDetGeo const & OpDetGeoFromOpDet(unsigned int OpDet) const
Number of OpDets in the whole detector.
void average_position(G4Step const &aStep, double *xzyPos) const
G4double sample_time(G4double tau1, G4double tau2) const
G4PhysicsTable * theFastIntegralTable
Encapsulate the construction of a single cyostat.
double ftf1_sampling_factor
double VisibleEnergyDeposit() const
void SetDirectLightPropFunctions(TF1 const *functions[8], double &d_break, double &d_max, double &tf1_sampling_factor) const
G4bool GetFiniteRiseTime() const
Float_t y1[n_points_granero]
G4double GetScintillationExcitationRatio() const
G4bool GetTrackSecondariesFirst() const
void AddEnergyDeposit(int n_elec, int n_photon, 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, std::string const &vol="EMPTY")
std::vector< double > propagation_time(G4ThreeVector x0, int OpChannel, int NPhotons, bool Reflected=false) const
G4bool fTrackSecondariesFirst
void ProcessStep(const G4Step &step)
void GetCenter(double *xyz, double localz=0.0) const
double finter_d(double *x, double *par)
double finter_r(double *x, double *par)
G4double scint_time(const G4Step &aStep, G4double ScintillationTime, G4double ScintillationRiseTime) const
std::map< double, double > tpbemission
Energy deposited on a readout Optical Detector by simulated tracks.
OpFastScintillation(const G4String &processName="Scintillation", G4ProcessType type=fElectromagnetic)
void Reset(const G4Step *step)
Float_t y2[n_points_geant4]
void SetReflectedCOLightPropFunctions(TF1 const *functions[5], double &t0_max, double &t0_break_point) const
G4double bi_exp(G4double t, G4double tau1, G4double tau2) const
bool StoreReflected() const
virtual G4VParticleChange * AtRestDoIt(const G4Track &aTrack, const G4Step &aStep)
G4PhysicsTable * theSlowIntegralTable
contains objects relating to OpDet hits
void BuildThePhysicsTable()
Use Geant4's user "hooks" to maintain a list of particles generated by Geant4.
float const * GetAllVisibilities(double const *xyz, bool wantReflected=false) const
void AddPhoton(size_t opchannel, sim::OnePhoton &&photon, bool Reflected=false)
void SetScintillationByParticleType(const G4bool)
bool RecordPhotonsProduced(const G4Step &aStep, double N)
TF1 * GetTimingTF1(double const *xyz) const
static IonizationAndScintillation * Instance()
G4double single_exp(G4double t, G4double tau2) const
TF1 const * functions_vis[5]
bool FillSimEnergyDeposits() const
G4PhysicsTable * GetFastIntegralTable() const
void AddOpDetBacktrackerRecord(sim::OpDetBacktrackerRecord soc, bool Reflected=false)
std::vector< double > GetVisibleTimeOnlyCathode(double, int) const
void AddLitePhoton(int opchannel, int time, int nphotons, bool Reflected=false)
G4bool GetScintillationByParticleType() const
void AddScintillationPhotons(TrackID_t trackID, timePDclock_t timePDclock, double numberPhotons, double const *xyz, double energy)
Add scintillation photons and energy to this OpticalDetector.
std::vector< double > GetVUVTime(double, int) const
Encapsulate the geometry of an optical detector.
static OpDetPhotonTable * Instance(bool LitePhotons=false)
bool bPropagate
Whether propagation of photons is enabled.
TF1 const * functions_vuv[8]
Singleton to access a unified treatment of ionization and scintillation in LAr.
double reemission_energy() const
contains information for a single step in the detector simulation
static int GetCurrentTrackID()
virtual G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
double NumberScintillationPhotons() const
G4EmSaturation * emSaturation
bool IncludeParPropTime() const
G4double GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *)
G4double GetMeanLifeTime(const G4Track &aTrack, G4ForceCondition *)
size_t NOpChannels() const
virtual bool ScintByParticleType() const =0
Namespace collecting geometry-related classes utilities.
G4double GetScintillationYieldFactor() const
art framework interface to geometry description
CLHEP::RandGeneral * rgen0
cet::coded_exception< error, detail::translate > exception
bool UseLitePhotons() const
double LandauPlusExpoFinal(double *x, double *par)
float const * GetReflT0s(double const *xyz) const