48 #include "G4ParticleTypes.hh" 49 #include "G4EmProcessSubType.hh" 53 #include "G4SystemOfUnits.hh" 54 #include "G4PhysicalConstants.hh" 56 #define E_PURITY 2*CLHEP::m //the electron absorption z-length 57 #define GRID_DENSITY 8.03*(CLHEP::g/CLHEP::cm3) //density of your grid material 68 : G4VRestDiscreteProcess(processName, type)
75 SetProcessSubType(fScintillation);
78 G4cout << GetProcessName() <<
" is created " << G4endl;
96 aParticleChange.Initialize(aTrack);
97 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
98 const G4Material* aMaterial = aTrack.GetMaterial();
100 aParticleChange.ProposeTrackStatus(fStopAndKill);
101 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
103 G4MaterialPropertiesTable* aMaterialPropertiesTable =
104 aMaterial->GetMaterialPropertiesTable();
105 if ( !aMaterialPropertiesTable ) {
106 aParticleChange.ProposeTrackStatus(fStopAndKill);
107 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
109 const G4ElementVector* theElementVector =
110 aMaterial->GetElementVector();
111 G4Element* Element = (*theElementVector)[0]; G4int z1;
112 if ( Element ) z1 = (G4int)(Element->GetZ());
else z1 = -1;
114 G4double z_start =
BORDER;
119 G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint();
120 G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
121 G4ThreeVector x0 = pPreStepPoint->GetPosition();
122 G4ThreeVector
x1 = pPostStepPoint->GetPosition();
123 G4double
t1 = pPostStepPoint->GetGlobalTime();
126 G4int Phase = aMaterial->GetState();
128 if ( Phase == kStateLiquid && x0[2] > (
GAT-5*
CLHEP::mm) &&
GAT != 0 ) {
130 aMaterial->GetTemperature(),fabs(aMaterialPropertiesTable->
132 aParticleChange.ProposeWeight(2.0);
133 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
139 if ( Phase == kStateLiquid || !
YieldFactor || x0[2] > z_anode ||
140 x1[2] > z_anode || fabs(x1[2]-x0[2]) < 1
e-7*
CLHEP::nm ||
141 (z1!=2 && z1!=10 && z1!=18 && z1!=36 && z1!=54) ) {
142 G4double KE = aParticle->GetKineticEnergy();
143 aParticleChange.ProposeTrackStatus(fStopAndKill);
144 aParticleChange.ProposeEnergy(0.);
145 aParticleChange.ProposeLocalEnergyDeposit(KE);
146 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
148 if ( x0[2] <= z_start && x1[2] <= z_start )
149 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
151 G4double ElectricField;
153 ElectricField = aMaterialPropertiesTable->
154 GetConstProperty(
"ELECTRICFIELD");
156 ElectricField = aMaterialPropertiesTable->
157 GetConstProperty(
"ELECTRICFIELDANODE");
161 if ( Density > 0. && Phase == kStateGas && (x0[2] > z_start ||
162 x1[2] > z_start) && aParticleChange.GetWeight() >= 1.0 ) {
163 aParticleChange.ProposeWeight(0);
164 G4double ExtractEff = -0.0012052 +
165 0.1638*ElectricField-0.0063782*
pow(ElectricField,2.);
166 if ( ElectricField > 10.0 ) ExtractEff = 1.00;
167 if ( ElectricField <= 0.0 ) ExtractEff = 0.00;
168 if ( ExtractEff < 0 ) ExtractEff = 0;
169 if ( ExtractEff > 1 ) ExtractEff = 1;
171 if (G4UniformRand() > ExtractEff || !ElectricField ||
172 (1/
E_eV[z1])*1e17*((ElectricField*1e3)/nDensity)<=
thr[z1]) {
173 aParticleChange.ProposeTrackStatus(fStopAndKill);
174 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
179 aParticleChange.ProposeEnergy(eDrift);
183 if ( G4UniformRand () >=
QE_EFF )
184 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
185 aParticleChange.SetNumberOfSecondaries(G4int(floor(
YieldFactor)));
186 if ( verboseLevel > 0 ) {
187 G4cout <<
"\n Exiting from G4S2Light::DoIt -- " 188 <<
"NumberOfSecondaries = " 189 << aParticleChange.GetNumberOfSecondaries() << G4endl;
193 G4double sampledEnergy;
194 G4DynamicParticle* aQuantum;
197 G4double cost = 1. - 2.*G4UniformRand();
198 G4double sint = std::sqrt((1.-cost)*(1.+cost));
200 G4double sinp = std::sin(phi);
201 G4double cosp = std::cos(phi);
202 G4double
px = sint*cosp; G4double
py = sint*sinp;
206 G4ParticleMomentum photonMomentum(px, py, pz);
209 G4double sx = cost*cosp; G4double sy = cost*sinp;
211 G4ThreeVector photonPolarization(sx, sy, sz);
212 G4ThreeVector perp = photonMomentum.cross(photonPolarization);
214 sinp = std::sin(phi); cosp = std::cos(phi);
215 photonPolarization = cosp * photonPolarization + sinp * perp;
216 photonPolarization = photonPolarization.unit();
219 sampledEnergy = G4RandGauss::shoot(
E_eV[z1]*
CLHEP::eV,0.2*CLHEP::eV);
220 if ( z1==54 && sampledEnergy>8.5*CLHEP::eV ) sampledEnergy = 8.5*
CLHEP::eV;
222 new G4DynamicParticle(G4OpticalPhoton::OpticalPhoton(),
224 aQuantum->SetPolarization(photonPolarization.x(),
225 photonPolarization.y(),
226 photonPolarization.z());
229 aQuantum->SetKineticEnergy(sampledEnergy);
231 G4cout <<
"sampledEnergy = " << sampledEnergy << G4endl;
234 G4double aSecondaryTime =
t1,
236 if(G4UniformRand()<SingTripRatio/(1+SingTripRatio))
237 aSecondaryTime -=
tau1[z1]*log(G4UniformRand());
238 else aSecondaryTime -=
239 tau3[z1]*log(G4UniformRand());
242 if ( x1[2] <
BORDER + GASGAP / 2. )
244 if ( x1[2] >
BORDER + GASGAP / 2. )
246 G4ThreeVector aSecondaryPosition =
x1;
249 G4Track* aSecondaryTrack =
250 new G4Track(aQuantum,aSecondaryTime,aSecondaryPosition);
251 aParticleChange.AddSecondary(aSecondaryTrack);
253 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
260 G4ForceCondition* condition)
262 const G4Material* aMaterial = aTrack.GetMaterial();
263 if ( !aMaterial )
return DBL_MIN;
264 const G4ElementVector* theElementVector = aMaterial->GetElementVector();
265 G4Element* Element = (*theElementVector)[0]; G4int z1;
266 if ( Element ) z1 = (G4int)(Element->GetZ());
else z1 = -1;
267 if ( (z1==2 || z1==10 || z1==18 || z1==36 || z1==54) &&
268 aMaterial->GetState() == kStateLiquid ) {
269 if ( aTrack.GetPosition()[2] < (
GAT-5*
CLHEP::mm) || aTrack.GetWeight() == 2 )
273 else if ((z1==2 || z1==10 || z1==18 || z1==36 || z1==54) &&
274 aMaterial->GetState()== kStateGas && aMaterial->GetDensity()>0.0*(
CLHEP::g/
CLHEP::cm3)) {
275 G4MaterialPropertiesTable* aMaterialPropertiesTable =
276 aMaterial->GetMaterialPropertiesTable();
277 if(!aMaterialPropertiesTable)
return DBL_MIN;
278 if ( aTrack.GetPosition()[2] < (
GAT-5*
CLHEP::mm) )
return DBL_MAX;
279 G4double ElectricField = fabs(aMaterialPropertiesTable->
280 GetConstProperty(
"ELECTRICFIELDANODE"));
282 G4double mfp, nDensity =
284 if ( (1/
E_eV[z1])*(ElectricField/nDensity)*1e17 ==
thr[z1] ) {
289 (nDensity*1
e-17*((1/
E_eV[z1])*(ElectricField/nDensity)*1e17-
thr[z1]));
298 *condition = NotForced;
299 const G4Material* aMaterial = aTrack.GetMaterial();
309 G4ForceCondition* condition)
311 *condition = InActivated;
318 double gas1a=395.50266631436,gas1b=-357384143.004642,gas1c=0.518110447340587;
320 double gas2a=-592981.611357632,gas2b=-90261.9643716643,
321 gas2c=-4911.83213989609,gas2d=-115.157545835228, gas2f=-0.990440443390298,
322 gas2g=1008.30998933704,gas2h=223.711221224885;
324 G4double edrift=0, gasdep=efieldinput/density, gas1fix=0, gas2fix=0;
326 if ( gasdep < 1.2e-19 && gasdep >= 0 ) edrift = 4e22*gasdep;
327 if ( gasdep < 3.5e-19 && gasdep >= 1.2
e-19 ) {
328 gas1fix = gas1b*
pow(gasdep,gas1c); edrift = gas1a*
pow(gasdep,gas1fix);
330 if ( gasdep < 3.8e-17 && gasdep >= 3.5
e-19 ) {
331 gas2fix = log(gas2g*gasdep);
332 edrift = (gas2a+gas2b*gas2fix+gas2c*
pow(gas2fix,2)+gas2d*
pow(gas2fix,3)+
333 gas2f*
pow(gas2fix,4))*(gas2h*exp(gasdep));
335 if ( gasdep >= 3.8
e-17 ) edrift = 6e21*gasdep-32279;
static constexpr double cm
static constexpr double g
static constexpr double cm3
kilovolt_as<> kilovolt
Type of potential stored in kilovolt, in double precision.
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
static constexpr double eV
G4double GetLiquidElectronDriftSpeed(double T, double F, G4bool M, G4int Z)
G4S2Light(const G4String &processName="S2", G4ProcessType type=fElectromagnetic)
G4bool fTrackSecondariesFirst
volt_as<> volt
Type of potential stored in volts, in double precision.
G4double GetGasElectronDriftSpeed(G4double efieldinput, G4double density)
G4double GetMeanLifeTime(const G4Track &aTrack, G4ForceCondition *)
G4VParticleChange * AtRestDoIt(const G4Track &aTrack, const G4Step &aStep)
static constexpr double mm
G4double GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *)