87 CLHEP::RandGauss GaussGen(
fEngine);
88 CLHEP::RandFlat UniformGen(
fEngine);
102 bool fTrackSecondariesFirst =
false;
103 bool fExcitedNucleus =
false;
104 bool fVeryHighEnergy =
false;
106 bool fMultipleScattering =
false;
109 if( aTrack.GetParentID() == 0 && aTrack.GetCurrentStepNumber() == 1 ) {
110 fExcitedNucleus =
false;
111 fVeryHighEnergy =
false;
113 fMultipleScattering =
false;
116 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
117 G4ParticleDefinition *pDef = aParticle->GetDefinition();
118 G4String particleName = pDef->GetParticleName();
119 const G4Material* aMaterial = aStep.GetPreStepPoint()->GetMaterial();
120 const G4Material* bMaterial = aStep.GetPostStepPoint()->GetMaterial();
122 if((particleName ==
"neutron" || particleName ==
"antineutron") &&
123 aStep.GetTotalEnergyDeposit() <= 0)
131 G4Element *ElementA = NULL, *ElementB = NULL;
133 const G4ElementVector* theElementVector1 =
134 aMaterial->GetElementVector();
135 ElementA = (*theElementVector1)[0];
138 const G4ElementVector* theElementVector2 =
139 bMaterial->GetElementVector();
140 ElementB = (*theElementVector2)[0];
142 G4int z1,z2,j=1; G4bool NobleNow=
false,NobleLater=
false;
143 if (ElementA) z1 = (G4int)(ElementA->GetZ());
else z1 = -1;
144 if (ElementB) z2 = (G4int)(ElementB->GetZ());
else z2 = -1;
145 if ( z1==2 || z1==10 || z1==18 || z1==36 || z1==54 ) {
155 if ( z2==2 || z2==10 || z2==18 || z2==36 || z2==54 ) {
166 if ( !NobleNow && !NobleLater )
171 G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint();
172 G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
173 G4ThreeVector
x1 = pPostStepPoint->GetPosition();
174 G4ThreeVector x0 = pPreStepPoint->GetPosition();
175 G4double evtStrt = pPreStepPoint->GetGlobalTime();
176 G4double
t0 = pPreStepPoint->GetLocalTime();
177 G4double
t1 = pPostStepPoint->GetLocalTime();
183 G4bool outside =
false, inside =
false, InsAndOuts =
false;
184 G4MaterialPropertiesTable* aMaterialPropertiesTable =
185 aMaterial->GetMaterialPropertiesTable();
186 if ( NobleNow && !NobleLater ) outside =
true;
187 if ( !NobleNow && NobleLater ) {
188 aMaterial = bMaterial; inside =
true; z1 = z2;
189 aMaterialPropertiesTable = bMaterial->GetMaterialPropertiesTable();
191 if ( NobleNow && NobleLater &&
192 aMaterial->GetDensity() != bMaterial->GetDensity() )
197 G4double nDensity = Density*
AVO;
198 G4int Phase = aMaterial->GetState();
199 G4double ElectricField(0.), FieldSign(0.);
200 G4bool GlobalFields =
false;
203 ElectricField = aMaterialPropertiesTable->GetConstProperty(
"ELECTRICFIELD");
207 if ( x1[2] <
WIN && x1[2] >
TOP && Phase == kStateGas )
208 ElectricField = aMaterialPropertiesTable->GetConstProperty(
"ELECTRICFIELDWINDOW");
209 else if ( x1[2] <
TOP && x1[2] >
ANE && Phase == kStateGas )
210 ElectricField = aMaterialPropertiesTable->GetConstProperty(
"ELECTRICFIELDTOP");
211 else if ( x1[2] <
ANE && x1[2] >
SRF && Phase == kStateGas )
212 ElectricField = aMaterialPropertiesTable->
213 GetConstProperty(
"ELECTRICFIELDANODE");
214 else if ( x1[2] <
SRF && x1[2] >
GAT && Phase == kStateLiquid )
215 ElectricField = aMaterialPropertiesTable->
216 GetConstProperty(
"ELECTRICFIELDSURFACE");
217 else if ( x1[2] <
GAT && x1[2] >
CTH && Phase == kStateLiquid )
218 ElectricField = aMaterialPropertiesTable->
219 GetConstProperty(
"ELECTRICFIELDGATE");
220 else if ( x1[2] <
CTH && x1[2] >
BOT && Phase == kStateLiquid )
221 ElectricField = aMaterialPropertiesTable->
222 GetConstProperty(
"ELECTRICFIELDCATHODE");
223 else if ( x1[2] <
BOT && x1[2] >
PMT && Phase == kStateLiquid )
224 ElectricField = aMaterialPropertiesTable->
225 GetConstProperty(
"ELECTRICFIELDBOTTOM");
227 ElectricField = aMaterialPropertiesTable->
228 GetConstProperty(
"ELECTRICFIELD");
230 if ( ElectricField >= 0 ) FieldSign = 1;
else FieldSign = -1;
232 G4double Temperature = aMaterial->GetTemperature();
233 G4double ScintillationYield, ResolutionScale, R0 = 1.0*
CLHEP::um,
234 DokeBirks[3], ThomasImel = 0.00, delta = 1*
CLHEP::mm;
235 DokeBirks[0] = 0.00; DokeBirks[2] = 1.00;
240 ScintillationYield = 1 / (41.3*
CLHEP::eV);
242 ResolutionScale = 0.2;
249 ScintillationYield = 1 / (29.2*
CLHEP::eV);
251 ResolutionScale = 0.13;
254 tau3 = GaussGen.fire(15.4e3*
CLHEP::ns,200*CLHEP::ns);
257 ScintillationYield = 1 / (19.5*
CLHEP::eV);
259 ResolutionScale = 0.107;
262 ThomasImel = 0.156977*
pow(ElectricField,-0.1);
263 DokeBirks[0] = 0.07*
pow((ElectricField/1.0e3),-0.85);
268 DokeBirks[0] = 0.0003;
270 } nDensity /= 39.948;
272 tau1 = GaussGen.fire(6.5*CLHEP::ns,0.8*CLHEP::ns);
273 tau3 = GaussGen.fire(1300*CLHEP::ns,50*CLHEP::ns);
274 tauR = GaussGen.fire(0.8*CLHEP::ns,0.2*CLHEP::ns);
277 if ( Phase == kStateGas ) ScintillationYield = 1 / (30.0*
CLHEP::eV);
278 else ScintillationYield = 1 / (15.0*
CLHEP::eV);
280 ResolutionScale = 0.05;
282 tau1 = GaussGen.fire(2.8*CLHEP::ns,.04*CLHEP::ns);
283 tau3 = GaussGen.fire(93.*CLHEP::ns,1.1*CLHEP::ns);
284 tauR = GaussGen.fire(12.*CLHEP::ns,.76*CLHEP::ns);
287 default: nDensity /= 131.293;
288 ScintillationYield = 48.814+0.80877*Density+2.6721*
pow(Density,2.);
293 ResolutionScale = 1.00 *
294 (0.12724-0.032152*Density-0.0013492*
pow(Density,2.));
296 if ( Phase == kStateLiquid ) {
297 ResolutionScale *= 1.5;
303 DokeBirks[0]= 19.171*
pow(ElectricField+25.552,-0.83057)+0.026772;
319 tau1 = GaussGen.fire(3.1*CLHEP::ns,.7*CLHEP::ns);
320 tau3 = GaussGen.fire(24.*CLHEP::ns,1.*CLHEP::ns);
322 else if ( Phase == kStateGas ) {
325 ScintillationYield = 1 / (12.98*
CLHEP::eV); }
327 G4double Townsend = (ElectricField/nDensity)*1e17;
328 DokeBirks[0] = 0.0000;
329 DokeBirks[2] = 0.1933*
pow(Density,2.6199)+0.29754 -
330 (0.045439*
pow(Density,2.4689)+0.066034)*log10(ElectricField);
331 if ( ElectricField>6990 ) DokeBirks[2]=0.0;
332 if ( ElectricField<1000 ) DokeBirks[2]=0.2;
333 if ( ElectricField<100. ) { DokeBirks[0]=0.18; DokeBirks[2]=0.58; }
334 if( Density < 0.061 ) ThomasImel = 0.041973*
pow(Density,1.8105);
335 else if( Density >= 0.061 && Density <= 0.167 )
336 ThomasImel=5.9583e-5+0.0048523*Density-0.023109*
pow(Density,2.);
337 else ThomasImel = 6.2552e-6*
pow(Density,-1.9963);
338 if(ElectricField)ThomasImel=1.2733e-5*
pow(Townsend/Density,-0.68426);
341 tau1 = GaussGen.fire(5.18*CLHEP::ns,1.55*CLHEP::ns);
342 tau3 = GaussGen.fire(100.1*CLHEP::ns,7.9*CLHEP::ns);
350 G4double anExcitationEnergy = ((
const G4Ions*)(pDef))->
351 GetExcitationEnergy();
352 G4double TotalEnergyDeposit =
353 aMaterialPropertiesTable->GetConstProperty(
"ENERGY_DEPOSIT_TOT" );
354 G4bool
convert =
false, annihil =
false;
356 if(pPreStepPoint->GetKineticEnergy()>=(2*CLHEP::electron_mass_c2) &&
357 !pPostStepPoint->GetKineticEnergy() &&
358 !aStep.GetTotalEnergyDeposit() && aParticle->GetPDGcode()==22) {
359 convert =
true; TotalEnergyDeposit = CLHEP::electron_mass_c2;
361 if(pPreStepPoint->GetKineticEnergy() &&
362 !pPostStepPoint->GetKineticEnergy() &&
363 aParticle->GetPDGcode()==-11) {
364 annihil =
true; TotalEnergyDeposit += aStep.GetTotalEnergyDeposit();
366 G4bool either =
false;
367 if(inside || outside || convert || annihil || InsAndOuts) either=
true;
370 !either && !fExcitedNucleus )
373 if ( !annihil ) TotalEnergyDeposit += aStep.GetTotalEnergyDeposit();
374 if ( !convert ) aMaterialPropertiesTable->
375 AddConstProperty(
"ENERGY_DEPOSIT_TOT", TotalEnergyDeposit );
377 TotalEnergyDeposit = aStep.GetTotalEnergyDeposit();
382 G4double InitialKinetEnergy = aMaterialPropertiesTable->
383 GetConstProperty(
"ENERGY_DEPOSIT_GOL" );
385 if ( InitialKinetEnergy == 0 ) {
386 G4double tE = pPreStepPoint->GetKineticEnergy()+anExcitationEnergy;
388 Phase == kStateLiquid && z1 == 54 ) tE = 9.4*
CLHEP::keV;
389 if ( fKr83m && ElectricField != 0 )
391 aMaterialPropertiesTable->
392 AddConstProperty (
"ENERGY_DEPOSIT_GOL", tE );
396 if ( anExcitationEnergy ) fExcitedNucleus =
true;
400 if(outside){ aMaterialPropertiesTable->
401 AddConstProperty(
"ENERGY_DEPOSIT_GOL",
402 InitialKinetEnergy-pPostStepPoint->GetKineticEnergy());
403 if(aMaterialPropertiesTable->
404 GetConstProperty(
"ENERGY_DEPOSIT_GOL")<0)
405 aMaterialPropertiesTable->AddConstProperty(
"ENERGY_DEPOSIT_GOL",0);
409 if(inside) { aMaterialPropertiesTable->
410 AddConstProperty(
"ENERGY_DEPOSIT_GOL",
411 InitialKinetEnergy+pPreStepPoint->GetKineticEnergy());
412 if ( TotalEnergyDeposit > 0 && InitialKinetEnergy == 0 ) {
413 aMaterialPropertiesTable->AddConstProperty(
"ENERGY_DEPOSIT_GOL",0);
414 TotalEnergyDeposit = .000000;
420 aMaterialPropertiesTable->
421 AddConstProperty(
"ENERGY_DEPOSIT_GOL",(-0.1*
CLHEP::keV)+
422 InitialKinetEnergy-pPostStepPoint->GetKineticEnergy());
423 InitialKinetEnergy = bMaterial->GetMaterialPropertiesTable()->
424 GetConstProperty(
"ENERGY_DEPOSIT_GOL");
425 bMaterial->GetMaterialPropertiesTable()->
426 AddConstProperty(
"ENERGY_DEPOSIT_GOL",(-0.1*
CLHEP::keV)+
427 InitialKinetEnergy+pPreStepPoint->GetKineticEnergy());
428 if(aMaterialPropertiesTable->
429 GetConstProperty(
"ENERGY_DEPOSIT_GOL")<0)
430 aMaterialPropertiesTable->AddConstProperty(
"ENERGY_DEPOSIT_GOL",0);
431 if ( bMaterial->GetMaterialPropertiesTable()->
432 GetConstProperty(
"ENERGY_DEPOSIT_GOL") < 0 )
433 bMaterial->GetMaterialPropertiesTable()->
434 AddConstProperty (
"ENERGY_DEPOSIT_GOL", 0 );
436 InitialKinetEnergy = aMaterialPropertiesTable->
437 GetConstProperty(
"ENERGY_DEPOSIT_GOL");
439 InitialKinetEnergy += 2*CLHEP::electron_mass_c2;
443 InitialKinetEnergy -= 2*CLHEP::electron_mass_c2;
445 aMaterialPropertiesTable->
446 AddConstProperty(
"ENERGY_DEPOSIT_GOL",InitialKinetEnergy);
447 if (anExcitationEnergy < 1
e-100 && aStep.GetTotalEnergyDeposit()==0 &&
448 aMaterialPropertiesTable->GetConstProperty(
"ENERGY_DEPOSIT_GOL")==0 &&
449 aMaterialPropertiesTable->GetConstProperty(
"ENERGY_DEPOSIT_TOT")==0)
453 if ( aTrack.GetCreatorProcess() )
454 procName = aTrack.GetCreatorProcess()->GetProcessName();
458 fMultipleScattering =
true;
465 fMultipleScattering =
true;
469 char xCoord[80];
char yCoord[80];
char zCoord[80];
473 sprintf(xCoord,
"POS_X_%d",i); sprintf(yCoord,
"POS_Y_%d",i);
474 sprintf(zCoord,
"POS_Z_%d",i);
475 pos[0] = aMaterialPropertiesTable->GetConstProperty(xCoord);
476 pos[1] = aMaterialPropertiesTable->GetConstProperty(yCoord);
477 pos[2] = aMaterialPropertiesTable->GetConstProperty(zCoord);
478 if ( sqrt(
pow(x1[0]-pos[0],2.)+
pow(x1[1]-pos[1],2.)+
479 pow(x1[2]-pos[2],2.)) < delta ) {
480 exists =
true;
break;
483 if(!exists && TotalEnergyDeposit) {
485 sprintf(xCoord,
"POS_X_%i",j); sprintf(yCoord,
"POS_Y_%i",j);
486 sprintf(zCoord,
"POS_Z_%i",j);
488 aMaterialPropertiesTable->AddConstProperty( xCoord, x1[0] );
489 aMaterialPropertiesTable->AddConstProperty( yCoord, x1[1] );
490 aMaterialPropertiesTable->AddConstProperty( zCoord, x1[2] );
492 aMaterialPropertiesTable->
493 AddConstProperty(
"TOTALNUM_INT_SITES", j );
501 G4double
a1 = ElementA->GetA();
502 z2 = pDef->GetAtomicNumber();
503 G4double
a2 = (G4double)(pDef->GetAtomicMass());
504 if ( particleName ==
"alpha" || (z2 == 2 && a2 == 4) )
506 if ( fAlpha ||
abs(aParticle->GetPDGcode()) == 2112 )
508 G4double epsilon = 11.5*(TotalEnergyDeposit/
CLHEP::keV)*
pow(z1,(-7./3.));
509 G4double
gamma = 3.*
pow(epsilon,0.15)+0.7*
pow(epsilon,0.6)+epsilon;
510 G4double kappa = 0.133*
pow(z1,(2./3.))*
pow(a2,(-1./2.))*(2./3.);
512 if ( (z1 == z2 && pDef->GetParticleType() ==
"nucleus") ||
513 particleName ==
"neutron" || particleName ==
"antineutron" ) {
515 if ( z1 == 18 && Phase == kStateLiquid )
520 if ( ElectricField == 0 && Phase == kStateLiquid ) {
521 if ( z1 == 54 ) ThomasImel = 0.19;
522 if ( z1 == 18 ) ThomasImel = 0.25;
525 0.3065*exp(-0.008806*
pow(ElectricField,0.76313));
530 G4double MeanNumberOfQuanta =
531 ScintillationYield*TotalEnergyDeposit;
534 G4double sigma = sqrt(ResolutionScale*MeanNumberOfQuanta);
536 G4int(floor(GaussGen.fire(MeanNumberOfQuanta,sigma)+0.5));
538 if (LeffVar > 1) LeffVar = 1.00000;
539 else if (LeffVar < 0) LeffVar = 0;
543 if(TotalEnergyDeposit < 1/ScintillationYield || NumQuanta < 0)
549 G4int NumIons = NumQuanta - NumExcitons;
555 G4double dE, dx=0, LET=0, recombProb;
557 if ( particleName !=
"e-" && particleName !=
"e+" && z1 != z2 &&
558 particleName !=
"mu-" && particleName !=
"mu+" ) {
564 if(LET) dx = dE/(Density*LET);
565 if(
abs(aParticle->GetPDGcode())==2112) dx=0;
569 if(dx) LET = (dE/dx)*(1/Density);
570 if ( LET > 0 && dE > 0 && dx > 0 ) {
573 particleName ==
"e-" ) {
576 DokeBirks[1] = DokeBirks[0]/(1-DokeBirks[2]);
578 recombProb = (DokeBirks[0]*LET)/(1+DokeBirks[1]*LET)+DokeBirks[2];
579 if ( Phase == kStateLiquid ) {
580 if ( z1 == 54 ) recombProb *= (Density/
Density_LXe);
581 if ( z1 == 18 ) recombProb *= (Density/
Density_LAr);
584 if(recombProb<0) recombProb=0;
585 if(recombProb>1) recombProb=1;
589 G4int NumPhotons = NumExcitons +
BinomFluct(NumIons,recombProb);
590 G4int NumElectrons = NumQuanta - NumPhotons;
601 char numExc[80];
char numIon[80];
char numPho[80];
char numEle[80];
602 sprintf(numExc,
"N_EXC_%i",counter); sprintf(numIon,
"N_ION_%i",counter);
603 aMaterialPropertiesTable->AddConstProperty( numExc, NumExcitons );
604 aMaterialPropertiesTable->AddConstProperty( numIon, NumIons );
605 sprintf(numPho,
"N_PHO_%i",counter); sprintf(numEle,
"N_ELE_%i",counter);
606 aMaterialPropertiesTable->AddConstProperty( numPho, NumPhotons );
607 aMaterialPropertiesTable->AddConstProperty( numEle, NumElectrons );
611 char trackL[80];
char time00[80];
char time01[80];
char energy[80];
612 sprintf(trackL,
"TRACK_%i",counter); sprintf(energy,
"ENRGY_%i",counter);
613 sprintf(time00,
"TIME0_%i",counter); sprintf(time01,
"TIME1_%i",counter);
614 delta = aMaterialPropertiesTable->GetConstProperty( trackL );
615 G4double energ = aMaterialPropertiesTable->GetConstProperty( energy );
617 aMaterialPropertiesTable->AddConstProperty( trackL, delta );
618 aMaterialPropertiesTable->AddConstProperty( energy, energ );
619 if ( TotalEnergyDeposit > 0 ) {
620 G4double deltaTime = aMaterialPropertiesTable->
621 GetConstProperty( time00 );
624 if (aParticle->GetCharge() != 0) {
626 aMaterialPropertiesTable->AddConstProperty( time00, t0 );
630 aMaterialPropertiesTable->AddConstProperty( time00, t1 );
632 deltaTime = aMaterialPropertiesTable->GetConstProperty( time01 );
635 aMaterialPropertiesTable->AddConstProperty( time01, t1 );
639 TotalEnergyDeposit=aMaterialPropertiesTable->
640 GetConstProperty(
"ENERGY_DEPOSIT_TOT");
641 InitialKinetEnergy=aMaterialPropertiesTable->
642 GetConstProperty(
"ENERGY_DEPOSIT_GOL");
643 if(InitialKinetEnergy >
HIENLIM &&
644 abs(aParticle->GetPDGcode()) != 2112) fVeryHighEnergy=
true;
646 if (fVeryHighEnergy && !fExcitedNucleus) safety = 0.2*
CLHEP::keV;
650 if( !anExcitationEnergy && pDef->GetParticleType() ==
"nucleus" &&
651 aTrack.GetTrackStatus() != fAlive && !fAlpha )
652 InitialKinetEnergy = TotalEnergyDeposit;
653 if ( particleName ==
"neutron" || particleName ==
"antineutron" )
654 InitialKinetEnergy = TotalEnergyDeposit;
659 if(
std::abs(TotalEnergyDeposit-InitialKinetEnergy)<safety ||
660 TotalEnergyDeposit>=InitialKinetEnergy ){
664 NumPhotons = 0; NumElectrons = 0;
666 sprintf(numPho,
"N_PHO_%d",i); sprintf(numEle,
"N_ELE_%d",i);
667 sprintf(trackL,
"TRACK_%d",i); sprintf(energy,
"ENRGY_%d",i);
669 dx += aMaterialPropertiesTable->GetConstProperty(trackL);
670 dE += aMaterialPropertiesTable->GetConstProperty(energy);
673 G4int buffer = 100;
if ( fVeryHighEnergy ) buffer = 1;
674 fParticleChange.SetNumberOfSecondaries(buffer*(NumPhotons+NumElectrons));
676 if (fTrackSecondariesFirst) {
677 if (aTrack.GetTrackStatus() == fAlive )
686 sprintf(xCoord,
"POS_X_%d",i); sprintf(yCoord,
"POS_Y_%d",i);
687 sprintf(zCoord,
"POS_Z_%d",i);
688 sprintf(numExc,
"N_EXC_%d",i); sprintf(numIon,
"N_ION_%d",i);
689 sprintf(numPho,
"N_PHO_%d",i); sprintf(numEle,
"N_ELE_%d",i);
690 NumExcitons = (G4int)aMaterialPropertiesTable->
691 GetConstProperty( numExc );
692 NumIons = (G4int)aMaterialPropertiesTable->
693 GetConstProperty( numIon );
694 sprintf(trackL,
"TRACK_%d",i); sprintf(energy,
"ENRGY_%d",i);
695 sprintf(time00,
"TIME0_%d",i); sprintf(time01,
"TIME1_%d",i);
696 delta = aMaterialPropertiesTable->GetConstProperty( trackL );
697 energ = aMaterialPropertiesTable->GetConstProperty( energy );
698 t0 = aMaterialPropertiesTable->GetConstProperty( time00 );
699 t1 = aMaterialPropertiesTable->GetConstProperty( time01 );
705 if ( (delta < R0 && !fVeryHighEnergy) || z2 == z1 || fAlpha ) {
706 if( z1 == 54 && ElectricField &&
707 Phase == kStateLiquid ) {
708 if (
abs ( z1 - z2 ) &&
709 abs ( aParticle->GetPDGcode() ) != 2112 ) {
710 ThomasImel = 0.056776*
pow(ElectricField,-0.11844);
712 ThomasImel=0.057675*
pow(ElectricField,-0.49362);
718 -0.15169*
pow((ElectricField+215.25),0.01811)+0.20952;
721 if (ThomasImel > 0.19) ThomasImel = 0.19;
722 if (ThomasImel < 0.00) ThomasImel = 0.00;
724 if ( Phase == kStateLiquid ) {
725 if ( z1 == 54 ) ThomasImel *=
pow((Density/2.84),0.3);
733 xi = (G4double(NumIons)/4.)*ThomasImel;
735 G4double NumIonsEff = 1.066e7*
pow(t0/CLHEP::ns,-1.303)*
736 (0.17163+162.32/(ElectricField+191.39));
737 if ( NumIonsEff > 1e6 ) NumIonsEff = 1e6;
738 xi = (G4double(NumIonsEff)/4.)*ThomasImel;
740 if ( fKr83m && ElectricField==0 )
741 xi = (G4double(1.3*NumIons)/4.)*ThomasImel;
742 recombProb = 1-log(1+xi)/xi;
743 if(recombProb<0) recombProb=0;
744 if(recombProb>1) recombProb=1;
747 NumPhotons = NumExcitons +
BinomFluct(NumIons,recombProb);
748 NumElectrons = (NumExcitons + NumIons) - NumPhotons;
750 aMaterialPropertiesTable->
751 AddConstProperty( numPho, NumPhotons );
752 aMaterialPropertiesTable->
753 AddConstProperty( numEle, NumElectrons );
758 NumPhotons = (G4int)aMaterialPropertiesTable->
759 GetConstProperty( numPho );
760 NumElectrons =(G4int)aMaterialPropertiesTable->
761 GetConstProperty( numEle );
763 G4double FanoFactor =0;
766 2575.9*
pow((ElectricField+15.154),-0.64064)-1.4707;
767 if ( fKr83m ) TotalEnergyDeposit = 4*
CLHEP::keV;
768 if ( (dE/
CLHEP::keV) <= 100 && ElectricField >= 0 ) {
769 G4double keVee = (TotalEnergyDeposit/(100.*
CLHEP::keV));
771 FanoFactor *= -0.00075+0.4625*keVee+34.375*
pow(keVee,2.);
773 FanoFactor *= 0.069554+1.7322*keVee-.80215*
pow(keVee,2.);
776 if ( Phase == kStateGas && Density>0.5 ) FanoFactor =
777 0.42857-4.7857*Density+7.8571*
pow(Density,2.);
778 if( FanoFactor <= 0 || fVeryHighEnergy ) FanoFactor = 0;
779 NumQuanta = NumPhotons + NumElectrons;
780 if(z1==54 && FanoFactor) NumElectrons = G4int(
781 floor(GaussGen.fire(NumElectrons,
782 sqrt(FanoFactor*NumElectrons))+0.5));
783 NumPhotons = NumQuanta - NumElectrons;
784 if ( NumElectrons <= 0 ) NumElectrons = 0;
785 if ( NumPhotons <= 0 ) NumPhotons = 0;
790 } NumElectrons = G4int(floor(NumElectrons*
phe_per_e+0.5));
797 if(fKr83m > 41) fKr83m = 0;
803 aMaterialPropertiesTable->AddConstProperty( numExc, 0 );
804 aMaterialPropertiesTable->AddConstProperty( numIon, 0 );
805 aMaterialPropertiesTable->AddConstProperty( numPho, 0 );
806 aMaterialPropertiesTable->AddConstProperty( numEle, 0 );
809 if( InitialKinetEnergy < MAX_ENE && InitialKinetEnergy >
MIN_ENE &&
810 !fMultipleScattering )
811 NumQuanta = NumPhotons + NumElectrons;
813 for(k = 0; k < NumQuanta; k++) {
814 G4double sampledEnergy;
815 G4DynamicParticle* aQuantum;
818 G4double cost = 1. - 2.*UniformGen.fire();
819 G4double sint = std::sqrt((1.-cost)*(1.+cost));
821 G4double sinp = std::sin(phi); G4double cosp = std::cos(phi);
822 G4double
px = sint*cosp; G4double
py = sint*sinp;
826 G4ParticleMomentum photonMomentum(px, py, pz);
829 if (k < NumPhotons) {
831 G4double sx = cost*cosp;
832 G4double sy = cost*sinp;
834 G4ThreeVector photonPolarization(sx, sy, sz);
835 G4ThreeVector perp = photonMomentum.cross(photonPolarization);
837 sinp = std::sin(phi);
838 cosp = std::cos(phi);
839 photonPolarization = cosp * photonPolarization + sinp * perp;
840 photonPolarization = photonPolarization.unit();
843 sampledEnergy = GaussGen.fire(PhotMean,PhotWidth);
844 aQuantum =
new G4DynamicParticle(G4OpticalPhoton::OpticalPhoton(),
846 aQuantum->SetPolarization(photonPolarization.x(),
847 photonPolarization.y(),
848 photonPolarization.z());
854 G4ParticleMomentum electronMomentum(0, 0, -FieldSign);
858 if ( Phase == kStateGas ) {
875 aQuantum->SetKineticEnergy(sampledEnergy);
884 G4double aSecondaryTime = t0+UniformGen.fire()*(t1-
t0)+evtStrt;
888 if ( aQuantum->GetDefinition()->
889 GetParticleName()==
"opticalphoton" ) {
890 if (
abs(z2-z1) && !fAlpha &&
891 abs(aParticle->GetPDGcode()) != 2112 ) {
898 if ( Phase == kStateLiquid && z1 == 54 )
899 tauR = 3.5*((1+0.41*LET)/(0.18*LET))*CLHEP::ns
900 *exp(-0.00900*ElectricField);
907 SingTripRatioX = GaussGen.fire(0.17,0.05);
908 SingTripRatioR = GaussGen.fire(0.8,0.2);
910 SingTripRatioR = 0.2701+0.003379*LET-4.7338e-5*
pow(LET,2.)
911 +8.1449e-6*
pow(LET,3.); SingTripRatioX = SingTripRatioR;
913 SingTripRatioX = GaussGen.fire(0.36,0.06);
914 SingTripRatioR = GaussGen.fire(0.5,0.2); }
918 SingTripRatioR = GaussGen.fire(2.3,0.51);
921 if (z1==18) SingTripRatioR = (-0.065492+1.9996
922 *exp(-dE/CLHEP::MeV))/(1+0.082154/
pow(dE/CLHEP::MeV,2.)) + 2.1811;
923 SingTripRatioX = SingTripRatioR;
928 SingTripRatioR = GaussGen.fire(7.8,1.5);
929 if (z1==18) SingTripRatioR = 0.22218*
pow(energ/
CLHEP::keV,0.48211);
930 SingTripRatioX = SingTripRatioR;
935 if ( k > NumExcitons ) {
938 aSecondaryTime += tauR*(1./UniformGen.fire()-1);
939 if(UniformGen.fire()<SingTripRatioR/(1+SingTripRatioR))
940 aSecondaryTime -= tau1*log(UniformGen.fire());
941 else aSecondaryTime -= tau3*log(UniformGen.fire());
944 if(UniformGen.fire()<SingTripRatioX/(1+SingTripRatioX))
945 aSecondaryTime -= tau1*log(UniformGen.fire());
946 else aSecondaryTime -= tau3*log(UniformGen.fire());
950 G4double gainField = 12;
951 G4double tauTrap = 884.83-62.069*gainField;
952 if ( Phase == kStateLiquid )
953 aSecondaryTime -= tauTrap*CLHEP::ns*log(UniformGen.fire());
965 x0[0] = aMaterialPropertiesTable->GetConstProperty( xCoord );
966 x0[1] = aMaterialPropertiesTable->GetConstProperty( yCoord );
967 x0[2] = aMaterialPropertiesTable->GetConstProperty( zCoord );
968 G4double radius = sqrt(
pow(x0[0],2.)+
pow(x0[1],2.));
971 if ( radius >=
R_TOL ) {
974 radius -=
R_TOL; phi = atan ( x0[1] / x0[0] );
975 x0[0] = fabs(radius*cos(phi))*((fabs(x0[0]))/(x0[0]));
976 x0[1] = fabs(radius*sin(phi))*((fabs(x0[1]))/(x0[1]));
979 G4ThreeVector aSecondaryPosition = x0;
980 if ( k >= NumPhotons &&
diffusion && ElectricField > 0 ) {
981 G4double D_T = 64*
pow(1
e-3*ElectricField,-.17);
983 G4double D_L = 13.859*
pow(1
e-3*ElectricField,-0.58559);
985 if ( Phase == kStateLiquid && z1 == 18 ) {
986 D_T = 93.342*
pow(ElectricField/nDensity,0.041322);
988 if ( Phase == kStateGas && z1 == 54 ) {
989 D_L=4.265+19097/ElectricField-1.7397e6/
pow(ElectricField,2.)+
990 1.2477e8/
pow(ElectricField,3.); D_T *= 0.01;
993 G4double vDrift = sqrt((2*sampledEnergy)/(
EMASS));
994 if (
BORDER == 0 ) x0[2] = 0;
995 G4double sigmaDT = sqrt(2*D_T*fabs(
BORDER-x0[2])/vDrift);
996 G4double sigmaDL = sqrt(2*D_L*fabs(
BORDER-x0[2])/vDrift);
997 G4double dr =
std::abs(GaussGen.fire(0.,sigmaDT));
999 aSecondaryPosition[0] += cos(phi) * dr;
1000 aSecondaryPosition[1] += sin(phi) * dr;
1001 aSecondaryPosition[2] += GaussGen.fire(0.,sigmaDL);
1002 radius = std::sqrt(
std::pow(aSecondaryPosition[0],2.)+
1003 std::pow(aSecondaryPosition[1],2.));
1004 if(aSecondaryPosition[2] >=
BORDER && Phase == kStateLiquid) {
1006 if(aSecondaryPosition[2] <=
PMT && !GlobalFields)
1007 aSecondaryPosition[2] =
PMT +
R_TOL;
1011 if ( aSecondaryTime < 0 ) aSecondaryTime = 0;
1022 aMaterialPropertiesTable->AddConstProperty( xCoord, 999*
CLHEP::km );
1023 aMaterialPropertiesTable->AddConstProperty( yCoord, 999*
CLHEP::km );
1024 aMaterialPropertiesTable->AddConstProperty( zCoord, 999*
CLHEP::km );
1025 aMaterialPropertiesTable->AddConstProperty( trackL, 0*
CLHEP::um );
1026 aMaterialPropertiesTable->AddConstProperty( energy, 0*
CLHEP::eV );
1027 aMaterialPropertiesTable->AddConstProperty( time00, DBL_MAX );
1028 aMaterialPropertiesTable->AddConstProperty( time01, -1*CLHEP::ns );
1033 aMaterialPropertiesTable->
1034 AddConstProperty(
"TOTALNUM_INT_SITES", 0 );
1035 aMaterialPropertiesTable->
1036 AddConstProperty(
"ENERGY_DEPOSIT_TOT", 0*
CLHEP::keV );
1037 aMaterialPropertiesTable->
1038 AddConstProperty(
"ENERGY_DEPOSIT_GOL", 0*CLHEP::MeV );
1039 fExcitedNucleus =
false;
static constexpr double cm
code to link reconstructed objects back to the MC truth information
static constexpr double keV
G4VParticleChange fParticleChange
pointer to G4VParticleChange
static constexpr double g
double fYieldFactor
turns scint. on/off
static constexpr double cm3
int fNumIonElectrons
number of ionization electrons produced by step
static constexpr double MeV
static constexpr double km
CLHEP::HepRandomEngine & fEngine
random engine
kilovolt_as<> kilovolt
Type of potential stored in kilovolt, in double precision.
bool exists(std::string path)
static G4ThermalElectron * ThermalElectron()
static constexpr double eV
static constexpr double cm2
def convert(inputfile, outputfile="wire-cell-garfield-fine-response.json.bz2", average=False, shaped=False)
G4double GetLiquidElectronDriftSpeed(double T, double F, G4bool M, G4int Z)
double gamma(double KE, const simb::MCParticle *part)
std::map< int, bool > fElementPropInit
int fNumScintPhotons
number of photons produced by the step
double fEnergyDep
energy deposited by the step
static constexpr double mm
G4double GetGasElectronDriftSpeed(G4double efieldinput, G4double density)
G4int BinomFluct(G4int N0, G4double prob)
G4double CalculateElectronLET(G4double E, G4int Z)
void InitMatPropValues(G4MaterialPropertiesTable *nobleElementMat, int z)
double fExcitationRatio
excitons to ions