Public Member Functions | Protected Attributes | List of all members
G4S2Light Class Reference

#include <G4S2Light.hh>

Inheritance diagram for G4S2Light:

Public Member Functions

 G4S2Light (const G4String &processName="S2", G4ProcessType type=fElectromagnetic)
 
 ~G4S2Light ()
 
G4bool IsApplicable (const G4ParticleDefinition &aParticleType)
 
G4double GetMeanFreePath (const G4Track &aTrack, G4double, G4ForceCondition *)
 
G4double GetMeanLifeTime (const G4Track &aTrack, G4ForceCondition *)
 
G4VParticleChange * PostStepDoIt (const G4Track &aTrack, const G4Step &aStep)
 
G4VParticleChange * AtRestDoIt (const G4Track &aTrack, const G4Step &aStep)
 
void SetTrackSecondariesFirst (const G4bool state)
 
G4bool GetTrackSecondariesFirst () const
 
void SetScintillationYieldFactor (const G4double yieldfactor)
 
G4double GetScintillationYieldFactor () const
 
void SetScintillationExcitationRatio (const G4double excitationratio)
 
G4double GetScintillationExcitationRatio () const
 

Protected Attributes

G4bool fTrackSecondariesFirst
 
G4double YieldFactor
 
G4double ExcitationRatio
 

Detailed Description

Definition at line 22 of file G4S2Light.hh.

Constructor & Destructor Documentation

G4S2Light::G4S2Light ( const G4String &  processName = "S2",
G4ProcessType  type = fElectromagnetic 
)

Definition at line 66 of file G4S2Light.cc.

68  : G4VRestDiscreteProcess(processName, type)
69 {
70  thr[18] = 0.190; E_eV[18] = 9.7; MolarMass[18] = 39.948;
71  tau1[18] = 6*CLHEP::ns; tau3[18] = 1600*CLHEP::ns; ConvertEff[18]=0.7857;
72  thr[54] = 0.474; E_eV[54] = 7.143; MolarMass[54] = 131.293;
73  ConvertEff[54] = 1.01; //50% when LXe TPC is dirty
74  //luxManager = LUXSimManager::GetManager();
75  SetProcessSubType(fScintillation);
76  fTrackSecondariesFirst = false;
77  if (verboseLevel>0) {
78  G4cout << GetProcessName() << " is created " << G4endl;
79  }
80 }
G4double thr[100]
Definition: G4S2Light.cc:59
G4double MolarMass[100]
Definition: G4S2Light.cc:61
G4double tau1[100]
Definition: G4S2Light.cc:61
G4double tau3[100]
Definition: G4S2Light.cc:61
G4bool fTrackSecondariesFirst
Definition: G4S2Light.hh:76
G4double ConvertEff[100]
Definition: G4S2Light.cc:61
G4double E_eV[100]
Definition: G4S2Light.cc:60
QAsciiDict< Entry > ns
G4S2Light::~G4S2Light ( )

Definition at line 82 of file G4S2Light.cc.

82 {} //destructor

Member Function Documentation

G4VParticleChange * G4S2Light::AtRestDoIt ( const G4Track &  aTrack,
const G4Step &  aStep 
)

Definition at line 85 of file G4S2Light.cc.

86 {
87  return G4S2Light::PostStepDoIt(aTrack, aStep);
88 }
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
Definition: G4S2Light.cc:91
G4double G4S2Light::GetMeanFreePath ( const G4Track &  aTrack,
G4double  ,
G4ForceCondition *  condition 
)

Definition at line 258 of file G4S2Light.cc.

261 {
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 )
270  return E_PURITY;
271  else return 0.000*CLHEP::mm;
272  }
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"));
281  ElectricField = ElectricField/(CLHEP::volt/CLHEP::cm);
282  G4double mfp, nDensity =
283  (aMaterial->GetDensity()/(CLHEP::g/CLHEP::cm3))/(MolarMass[z1])*AVO;
284  if ( (1/E_eV[z1])*(ElectricField/nDensity)*1e17 == thr[z1] ) {
285  mfp = 0*CLHEP::cm;
286  }
287  else { //denominator of formula OK
288  mfp = 1 /
289  (nDensity*1e-17*((1/E_eV[z1])*(ElectricField/nDensity)*1e17-thr[z1]));
290  }
291  //equation 8 within Monteiro's paper JINST 2007 (where 140=1/7.14.. eV)
292  mfp*=CLHEP::cm/ConvertEff[z1];
293  if(mfp<0)mfp=0;
294  if(mfp>GASGAP/2.7)mfp=GASGAP/exp(1);
295  return mfp; //mean free path for 1 photon
296  }
297  else {
298  *condition = NotForced;
299  const G4Material* aMaterial = aTrack.GetMaterial();
300  if ( aMaterial->GetDensity() == GRID_DENSITY )
301  return DBL_MAX; //pass electrons through grid wires
302  return 0*CLHEP::nm; //kill elsewhere
303  }
304 }
static constexpr double cm
Definition: Units.h:68
static constexpr double g
Definition: Units.h:144
G4double thr[100]
Definition: G4S2Light.cc:59
#define GAT
Definition: G4S1Light.hh:39
static constexpr double cm3
Definition: Units.h:70
G4double MolarMass[100]
Definition: G4S2Light.cc:61
#define AVO
Definition: G4S1Light.hh:24
#define E_PURITY
Definition: G4S2Light.cc:56
const double e
volt_as<> volt
Type of potential stored in volts, in double precision.
G4double ConvertEff[100]
Definition: G4S2Light.cc:61
#define GASGAP
Definition: G4S1Light.hh:28
static constexpr double mm
Definition: Units.h:65
#define GRID_DENSITY
Definition: G4S2Light.cc:57
G4double E_eV[100]
Definition: G4S2Light.cc:60
G4double G4S2Light::GetMeanLifeTime ( const G4Track &  aTrack,
G4ForceCondition *  condition 
)

Definition at line 308 of file G4S2Light.cc.

310 {
311  *condition = InActivated;
312  return DBL_MAX;
313 }
G4double G4S2Light::GetScintillationExcitationRatio ( ) const
inline

Definition at line 128 of file G4S2Light.hh.

129 {
130  return ExcitationRatio;
131 }
G4double ExcitationRatio
Definition: G4S2Light.hh:78
G4double G4S2Light::GetScintillationYieldFactor ( ) const
inline

Definition at line 116 of file G4S2Light.hh.

117 {
118  return YieldFactor;
119 }
G4double YieldFactor
Definition: G4S2Light.hh:77
G4bool G4S2Light::GetTrackSecondariesFirst ( ) const
inline

Definition at line 104 of file G4S2Light.hh.

105 {
106  return fTrackSecondariesFirst;
107 }
G4bool fTrackSecondariesFirst
Definition: G4S2Light.hh:76
G4bool G4S2Light::IsApplicable ( const G4ParticleDefinition &  aParticleType)
inline

Definition at line 90 of file G4S2Light.hh.

91 {
92  if (aParticleType.GetParticleName() != "thermalelectron") return false;
93 
94  return true;
95 }
G4VParticleChange * G4S2Light::PostStepDoIt ( const G4Track &  aTrack,
const G4Step &  aStep 
)

Definition at line 91 of file G4S2Light.cc.

92 {
93 // The function where all the action happens! Not yet well commented, as this
94 // is but an alpha version of the electroluminescence code
95  YieldFactor = 1.000;
96  aParticleChange.Initialize(aTrack);
97  const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
98  const G4Material* aMaterial = aTrack.GetMaterial();
99  if ( !aMaterial ) {
100  aParticleChange.ProposeTrackStatus(fStopAndKill);
101  return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
102  }
103  G4MaterialPropertiesTable* aMaterialPropertiesTable =
104  aMaterial->GetMaterialPropertiesTable();
105  if ( !aMaterialPropertiesTable ) {
106  aParticleChange.ProposeTrackStatus(fStopAndKill);
107  return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
108  }
109  const G4ElementVector* theElementVector =
110  aMaterial->GetElementVector();
111  G4Element* Element = (*theElementVector)[0]; G4int z1;
112  if ( Element ) z1 = (G4int)(Element->GetZ()); else z1 = -1;
113  G4double z_anode = BORDER + GASGAP;
114  G4double z_start = BORDER;
115  //if(luxManager->GetGasRun()) z_start=GAT;
116  tau1[54] = G4RandGauss::shoot(5.18*CLHEP::ns,1.55*CLHEP::ns);
117  tau3[54] = G4RandGauss::shoot(100.1*CLHEP::ns,7.9*CLHEP::ns);
118 
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();
124  G4double Density = aMaterial->GetDensity()/(CLHEP::g/CLHEP::cm3);
125  G4double nDensity = (Density/MolarMass[z1])*AVO;
126  G4int Phase = aMaterial->GetState();
127 
128  if ( Phase == kStateLiquid && x0[2] > (GAT-5*CLHEP::mm) && GAT != 0 ) {
129  aParticleChange.ProposeEnergy(GetLiquidElectronDriftSpeed(
130  aMaterial->GetTemperature(),fabs(aMaterialPropertiesTable->
131  GetConstProperty("ELECTRICFIELDSURFACE")/(CLHEP::volt/CLHEP::cm)),MillerDriftSpeed,z1));
132  aParticleChange.ProposeWeight(2.0);
133  return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
134  }
135 
136  // absorb the electron if you are in liquid and there is non-perfect
137  // purity, you turned S2 off with YieldFactor, the e- is above the
138  // anode in the gas already, or it's not present in a noble element
139  if ( Phase == kStateLiquid || !YieldFactor || x0[2] > z_anode ||
140  x1[2] > z_anode || fabs(x1[2]-x0[2]) < 1e-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);
147  }
148  if ( x0[2] <= z_start && x1[2] <= z_start )
149  return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
150 
151  G4double ElectricField;
152  if(!WIN && !TOP && !ANE && !SRF && !GAT && !CTH && !BOT && !PMT)
153  ElectricField = aMaterialPropertiesTable->
154  GetConstProperty("ELECTRICFIELD");
155  else
156  ElectricField = aMaterialPropertiesTable->
157  GetConstProperty("ELECTRICFIELDANODE");
158  ElectricField =
159  fabs(ElectricField/(CLHEP::kilovolt/CLHEP::cm));
160 
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 + //Aprile 2004 IEEE No.5
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;
170  //if ( luxManager->GetGasRun() ) 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);
175  }
176  else {
177  G4double eDrift =
178  GetGasElectronDriftSpeed(1000.*ElectricField,nDensity);
179  aParticleChange.ProposeEnergy(eDrift);
180  }
181  }
182 
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;
190  }
191 
192  // start particle creation
193  G4double sampledEnergy;
194  G4DynamicParticle* aQuantum;
195 
196  // Generate random direction
197  G4double cost = 1. - 2.*G4UniformRand();
198  G4double sint = std::sqrt((1.-cost)*(1.+cost));
199  G4double phi = CLHEP::twopi*G4UniformRand();
200  G4double sinp = std::sin(phi);
201  G4double cosp = std::cos(phi);
202  G4double px = sint*cosp; G4double py = sint*sinp;
203  G4double pz = cost;
204 
205  // Create momentum direction vector
206  G4ParticleMomentum photonMomentum(px, py, pz);
207 
208  // Determine polarization of new photon
209  G4double sx = cost*cosp; G4double sy = cost*sinp;
210  G4double sz = -sint;
211  G4ThreeVector photonPolarization(sx, sy, sz);
212  G4ThreeVector perp = photonMomentum.cross(photonPolarization);
213  phi = CLHEP::twopi*G4UniformRand();
214  sinp = std::sin(phi); cosp = std::cos(phi);
215  photonPolarization = cosp * photonPolarization + sinp * perp;
216  photonPolarization = photonPolarization.unit();
217 
218  // Generate a new photon:
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;
221  aQuantum =
222  new G4DynamicParticle(G4OpticalPhoton::OpticalPhoton(),
223  photonMomentum);
224  aQuantum->SetPolarization(photonPolarization.x(),
225  photonPolarization.y(),
226  photonPolarization.z());
227 
228  //assign energy to make particle real
229  aQuantum->SetKineticEnergy(sampledEnergy);
230  if (verboseLevel>1)
231  G4cout << "sampledEnergy = " << sampledEnergy << G4endl;
232 
233  // electroluminesence emission time distribution
234  G4double aSecondaryTime = t1,
235  SingTripRatio=.1; //guess: revisit
236  if(G4UniformRand()<SingTripRatio/(1+SingTripRatio))
237  aSecondaryTime -= tau1[z1]*log(G4UniformRand());
238  else aSecondaryTime -=
239  tau3[z1]*log(G4UniformRand());
240 
241  //the position of the new secondary particle
242  if ( x1[2] < BORDER + GASGAP / 2. )
243  x1[2] += 0.001*CLHEP::mm;
244  if ( x1[2] > BORDER + GASGAP / 2. )
245  x1[2] -= 0.001*CLHEP::mm;
246  G4ThreeVector aSecondaryPosition = x1;
247 
248  // GEANT4 business: stuff you need to make a new track
249  G4Track* aSecondaryTrack =
250  new G4Track(aQuantum,aSecondaryTime,aSecondaryPosition);
251  aParticleChange.AddSecondary(aSecondaryTrack);
252 
253  return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
254 }
static constexpr double cm
Definition: Units.h:68
#define WIN
Definition: G4S1Light.hh:35
#define BORDER
Definition: G4S1Light.hh:29
#define MillerDriftSpeed
Definition: G4S1Light.hh:26
static constexpr double g
Definition: Units.h:144
G4double thr[100]
Definition: G4S2Light.cc:59
#define TOP
#define GAT
Definition: G4S1Light.hh:39
#define QE_EFF
Definition: G4S1Light.hh:31
static constexpr double cm3
Definition: Units.h:70
constexpr T pow(T x)
Definition: pow.h:72
G4double MolarMass[100]
Definition: G4S2Light.cc:61
G4double YieldFactor
Definition: G4S2Light.hh:77
G4double tau1[100]
Definition: G4S2Light.cc:61
G4double tau3[100]
Definition: G4S2Light.cc:61
#define ANE
Definition: G4S1Light.hh:37
kilovolt_as<> kilovolt
Type of potential stored in kilovolt, in double precision.
#define AVO
Definition: G4S1Light.hh:24
#define SRF
Definition: G4S1Light.hh:38
const double e
#define BOT
Definition: G4S1Light.hh:41
static constexpr double eV
Definition: Units.h:127
G4double GetLiquidElectronDriftSpeed(double T, double F, G4bool M, G4int Z)
#define CTH
Definition: G4S1Light.hh:40
#define PMT
Definition: G4S1Light.hh:42
volt_as<> volt
Type of potential stored in volts, in double precision.
G4double GetGasElectronDriftSpeed(G4double efieldinput, G4double density)
Definition: G4S2Light.cc:315
int twopi
Definition: units.py:12
#define GASGAP
Definition: G4S1Light.hh:28
static constexpr double mm
Definition: Units.h:65
G4double E_eV[100]
Definition: G4S2Light.cc:60
QAsciiDict< Entry > ns
double Density(double r)
Definition: PREM.cxx:18
void G4S2Light::SetScintillationExcitationRatio ( const G4double  excitationratio)
inline

Definition at line 122 of file G4S2Light.hh.

123 {
124  ExcitationRatio = excitationratio;
125 }
G4double ExcitationRatio
Definition: G4S2Light.hh:78
void G4S2Light::SetScintillationYieldFactor ( const G4double  yieldfactor)
inline

Definition at line 110 of file G4S2Light.hh.

111 {
112  YieldFactor = yieldfactor;
113 }
G4double YieldFactor
Definition: G4S2Light.hh:77
void G4S2Light::SetTrackSecondariesFirst ( const G4bool  state)
inline

Definition at line 98 of file G4S2Light.hh.

99 {
100  fTrackSecondariesFirst = state;
101 }
G4bool fTrackSecondariesFirst
Definition: G4S2Light.hh:76

Member Data Documentation

G4double G4S2Light::ExcitationRatio
protected

Definition at line 78 of file G4S2Light.hh.

G4bool G4S2Light::fTrackSecondariesFirst
protected

Definition at line 76 of file G4S2Light.hh.

G4double G4S2Light::YieldFactor
protected

Definition at line 77 of file G4S2Light.hh.


The documentation for this class was generated from the following files: