32 using namespace G4XTankSimulatorAG;
34 #include <G4Version.hh>
36 #include <fwk/CentralConfig.h>
38 #include <utl/Reader.h>
39 #include <utl/AugerException.h>
40 #include <utl/ErrorLogger.h>
41 #include <utl/MathConstants.h>
42 #include <utl/AugerException.h>
90 : G4VContinuousProcess(processName)
95 if (verboseLevel > 0) G4cerr << GetProcessName() <<
" is created "
101 const G4double betat = 7.658e-23 *
m3 /
MeV;
103 const G4double kboltz = 8.61739e-11 *
MeV /
kelvin;
105 const G4double temp = 283.15 *
kelvin;
106 const G4double hc4 =
pow(h_Planck * c_light, 4);
158 const double& collectionEfficiency =
163 std::vector<double>::iterator fIt;
165 (*fIt) *= collectionEfficiency;
188 pmt1.
GetY(pmt1Coord) *
m,
189 pmt1.
GetZ(pmt1Coord) *
m);
192 pmt2.
GetY(pmt2Coord) *
m,
193 pmt2.
GetZ(pmt2Coord) *
m);
196 pmt3.
GetY(pmt3Coord) *
m,
197 pmt3.
GetZ(pmt3Coord) *
m);
199 for(
unsigned int k=1; k<4; ++k)
216 return (aParticle.GetPDGCharge() != 0);
241 G4PhysicsOrderedFreeVector *v;
244 for (G4int i = 0; i < PhysicsTableSize; ++i) {
246 v =
static_cast<G4PhysicsOrderedFreeVector *
>((*fThePhysicsTable)[i]);
254 const G4Step& aStep) {
258 aParticleChange.Initialize(aTrack);
259 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
260 const G4Material* aMaterial = aTrack.GetMaterial();
261 G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint();
262 G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
264 const G4ThreeVector x0 = pPreStepPoint->GetPosition();
265 const G4ThreeVector p0 = aStep.GetDeltaPosition().unit();
266 const G4double t0 = pPreStepPoint->GetGlobalTime();
268 if (t0 > 1.0e6)
return G4VContinuousProcess::AlongStepDoIt(aTrack, aStep);
270 G4ThreeVector aPrimaryDirection = pPreStepPoint->GetMomentumDirection();
272 const G4double cosAlpha = aPrimaryDirection.z();
273 const G4double sinAlpha =
sqrt(1.0 - (cosAlpha * cosAlpha));
274 const G4double cosBeta = aPrimaryDirection.x() / sinAlpha;
275 const G4double sinBeta = aPrimaryDirection.y() / sinAlpha;
277 G4MaterialPropertiesTable* aMaterialPropertiesTable =
278 aMaterial->GetMaterialPropertiesTable();
280 if (!aMaterialPropertiesTable)
281 return G4VContinuousProcess::AlongStepDoIt(aTrack, aStep);
283 const G4MaterialPropertyVector* Rindex =
284 aMaterialPropertiesTable->GetProperty(
"RINDEX");
287 return G4VContinuousProcess::AlongStepDoIt(aTrack, aStep);
291 if (MeanNumPhotons <= 0.0) {
292 aParticleChange.SetNumberOfSecondaries(0);
293 return G4VContinuousProcess::AlongStepDoIt(aTrack, aStep);
296 MeanNumPhotons *= aStep.GetStepLength();
298 G4int NumPhotons =
static_cast<G4int
>(G4Poisson(MeanNumPhotons));
302 aParticleChange.SetNumberOfSecondaries(0);
304 return G4VContinuousProcess::AlongStepDoIt(aTrack, aStep);
306 #if (G4VERSION_NUMBER < 920)
307 const G4double Pmin = Rindex->GetMinPhotonMomentum();
308 const G4double Pmax = Rindex->GetMaxPhotonMomentum();
310 const G4double Pmin = Rindex->GetMinPhotonEnergy();
311 const G4double Pmax = Rindex->GetMaxPhotonEnergy();
314 const G4double dp = Pmax - Pmin;
315 const G4double nMax = Rindex->GetMaxProperty();
317 const G4double betaInverse = aParticle->GetTotalEnergy() /
318 aParticle->GetTotalMomentum();
320 const G4double maxCos = betaInverse / nMax;
321 const G4double maxSin2 = (1.0 - (maxCos * maxCos));
323 const double minQEMomentum =
fQE[0].X();
330 G4double rand, cosTheta, sin2Theta;
331 G4double phi, sinTheta, px, py, pz;
333 G4double delta, deltaTime;
334 G4double sinThetaSinPhi, sinThetaCosPhi;
336 double absorptionMFP;
338 for (G4int i = 0; i < NumPhotons; ++i) {
340 rand = G4UniformRand();
344 sin2Theta = (1.0 - (cosTheta * cosTheta));
345 rand = G4UniformRand();
346 }
while ((rand * maxSin2) > sin2Theta);
358 G4double SampledRI_Sq, RIConst;
361 int iFirstValidBin_Wat = 0;
372 RIConst = (SampledRI_Sq + 2.0) * (SampledRI_Sq - 1.0);
377 invSumMFP = 1.0 / (absorptionMFP + rayleighMFP);
379 fInvMFP = (1.0 / absorptionMFP) + (1.0 / rayleighMFP);
384 sinTheta =
sqrt(sin2Theta);
385 rand = G4UniformRand();
388 sinThetaSinPhi = sin(phi) * sinTheta;
389 sinThetaCosPhi = cos(phi) * sinTheta;
391 px = (cosAlpha * cosBeta * sinThetaCosPhi) - (sinBeta * sinThetaSinPhi)
392 + (cosBeta * sinAlpha * cosTheta);
393 py = (cosAlpha * sinBeta * sinThetaCosPhi) + (cosBeta * sinThetaSinPhi)
394 + (sinBeta * sinAlpha * cosTheta);
395 pz = (cosAlpha * cosTheta) - (sinAlpha * sinThetaCosPhi);
401 rand = G4UniformRand();
402 delta = rand * aStep.GetStepLength();
403 deltaTime = delta / ((pPreStepPoint->GetVelocity() +
404 pPostStepPoint->GetVelocity()) / 2.0);
417 if (verboseLevel > 0) {
418 G4cerr <<
"\n Exiting from G4Cerenkov::DoIt -- NumberOfSecondaries = "
419 << aParticleChange.GetNumberOfSecondaries() << G4endl;
422 return G4VContinuousProcess::AlongStepDoIt(aTrack, aStep);
434 const G4MaterialTable* theMaterialTable= G4Material::GetMaterialTable();
435 G4int numOfMaterials = G4Material::GetNumberOfMaterials();
438 G4PhysicsOrderedFreeVector *aPhysicsOrderedFreeVector;
439 G4Material *aMaterial;
440 G4MaterialPropertiesTable *aMaterialPropertiesTable;
441 G4MaterialPropertyVector *theRIndexVector;
442 G4double currentRI, currentPM, currentCAI;
443 G4double prevRI, prevPM, prevCAI;
445 for (G4int i = 0; i < numOfMaterials; ++i) {
447 aPhysicsOrderedFreeVector =
new G4PhysicsOrderedFreeVector();
448 aMaterial = (*theMaterialTable)[i];
449 aMaterialPropertiesTable = aMaterial->GetMaterialPropertiesTable();
451 if (aMaterialPropertiesTable) {
453 theRIndexVector = aMaterialPropertiesTable->GetProperty(
"RINDEX");
455 if (theRIndexVector) {
457 theRIndexVector->ResetIterator();
458 ++(*theRIndexVector);
459 currentRI = theRIndexVector->GetProperty();
461 if (currentRI > 1.0) {
463 #if (G4VERSION_NUMBER < 920)
464 currentPM = theRIndexVector->GetPhotonMomentum();
466 currentPM = theRIndexVector->GetPhotonEnergy();
470 aPhysicsOrderedFreeVector->InsertValues(currentPM , currentCAI);
473 prevCAI = currentCAI;
475 while(++(*theRIndexVector)) {
477 currentRI = theRIndexVector->GetProperty();
479 #if (G4VERSION_NUMBER < 920)
480 currentPM = theRIndexVector->GetPhotonMomentum();
482 currentPM = theRIndexVector->GetPhotonEnergy();
485 currentCAI = 0.5 * ((1.0 / (prevRI * prevRI)) +
486 (1.0 / (currentRI * currentRI)));
487 currentCAI = prevCAI + ((currentPM - prevPM) * currentCAI);
488 aPhysicsOrderedFreeVector->InsertValues(currentPM, currentCAI);
490 prevCAI = currentCAI;
509 G4double, G4double, G4double &) {
514 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
515 const G4Material* aMaterial = aTrack.GetMaterial();
517 G4MaterialPropertiesTable* aMaterialPropertiesTable =
518 aMaterial->GetMaterialPropertiesTable();
520 if (!aMaterialPropertiesTable)
523 const G4MaterialPropertyVector* Rindex =
524 aMaterialPropertiesTable->GetProperty(
"RINDEX");
531 if (meanNumPhotons <= 0.0)
541 const G4Material* aMaterial,
542 const G4MaterialPropertyVector* Rindex)
const {
543 const G4double Rfact = 369.81 / (
eV *
cm);
545 if (aParticle->GetTotalMomentum() <= 0.0)
548 G4double betaInverse = aParticle->GetTotalEnergy() /
549 aParticle->GetTotalMomentum();
551 G4int materialIndex = aMaterial->GetIndex();
553 G4PhysicsOrderedFreeVector* CerenkovAngleIntegrals =
556 if (!(CerenkovAngleIntegrals->IsFilledVectorExist()))
559 #if (G4VERSION_NUMBER < 920)
560 G4double Pmin = Rindex->GetMinPhotonMomentum();
561 G4double Pmax = Rindex->GetMaxPhotonMomentum();
563 G4double Pmin = Rindex->GetMinPhotonEnergy();
564 G4double Pmax = Rindex->GetMaxPhotonEnergy();
567 G4double nMin = Rindex->GetMinProperty();
568 G4double nMax = Rindex->GetMaxProperty();
569 G4double CAImax = CerenkovAngleIntegrals->GetMaxValue();
572 if (nMax < betaInverse) {
577 }
else if (nMin > betaInverse) {
584 #if (G4VERSION_NUMBER < 920)
585 Pmin = Rindex->GetPhotonMomentum(betaInverse);
587 Pmin = Rindex->GetPhotonEnergy(betaInverse);
591 G4double CAImin = CerenkovAngleIntegrals->GetValue(Pmin, isOutRange);
592 ge = CAImax - CAImin;
594 if (verboseLevel>0) {
595 G4cerr <<
"CAImin = " << CAImin << G4endl;
596 G4cerr <<
"ge = " << ge << G4endl;
601 G4double charge = aParticle->GetDefinition()->GetPDGCharge();
602 G4double numPhotons = Rfact *
pow((charge /
eplus), 2) *
603 (dp - ge * betaInverse*betaInverse);
616 const G4double rand = 2.0 * G4UniformRand() - 1.0;
617 const G4double cosTheta= (rand < 0.0)?
618 (-
pow(-rand, 1.0 / 3.0)):
pow(rand, 1.0 / 3.0);
619 const G4double sinTheta =
sqrt(1.0 - cosTheta * cosTheta);
620 const G4double phi = 2.0 *
utl::kPi * G4UniformRand();
621 const G4double cosPhi = cos(phi);
622 const G4double sinPhi = sin(phi);
626 const G4double k = 1.0 /
sqrt(1.0 - c * c);
627 const G4double R11 = k *
b;
628 const G4double R12 = k * a *
c;
629 const G4double R21 = -k *
a;
630 const G4double R22 = k * b *
c;
631 const G4double R32 = -1.0 / k;
639 if (G4UniformRand() < 0.5) {
641 x = sinTheta * cosPhi;
642 y = sinTheta * sinPhi;
645 (R21 * x + R22 * y + b * z),
647 x = cosTheta * cosPhi;
648 y = cosTheta * sinPhi;
651 (R21 * x + R22 * y + b * z),
656 x = sinTheta * cosPhi;
657 y = sinTheta * sinPhi;
660 (R21 * x + R22 * y + b * z),
662 x = -cosTheta * cosPhi;
663 y = -cosTheta * sinPhi;
667 (R21 * x + R22 * y + b * z),
698 G4ThreeVector displacement;
701 for(
unsigned int i=1; i<4; ++i){
703 closest = (displacement.x()*displacement.x()+displacement.y()*displacement.y())/
fDomeRadiusSq +
706 closest = (displacement.x()*displacement.x()+displacement.y()*displacement.y())/
fInterfaceRadiusSq +
709 closest = (displacement.x()*displacement.x()+displacement.y()*displacement.y())/
fPMTRadiusSq +
711 if (closest < 1. && -displacement.z() >
fHeightz ) {
733 Dead = TransitionToDome<1>(flag);
738 Dead = TransitionToDome<2>(flag);
743 Dead = TransitionToDome<3>(flag);
751 G4double DistanceToFloor, DistanceToWall, DistanceTravelled,
Distance;
752 G4double DistanceToRoof, DistanceToPMT1, DistanceToPMT2, DistanceToPMT3;
753 G4double alpha, beta, gamma;
756 G4double closest1, closest2, closest3;
757 G4ThreeVector closest, Displacement1, Displacement2, Displacement3;
758 G4double DotProduct, rand, DistanceToPMT;
759 G4int HitPMT, TargetPMT = -1, Target;
767 WARNING(
"The z component of the momentul is 0, skipping photon.");
781 const double distance=alpha * alpha - beta;
783 WARNING(
"Distance to wall is not finite, skipping photon");
787 DistanceToWall =
sqrt(distance) - alpha;
790 rand = G4UniformRand();
791 TestVal=(DistanceToWall < DistanceToFloor)?
792 (1.0 - exp(-DistanceToWall *
fInvMFP)):(1.0 - exp(-DistanceToFloor * fInvMFP));
794 if (rand < TestVal) {
798 DistanceTravelled = -log(1.0 - (rand / fRayleighFrac)) /
fInvMFP;
802 if ((fPhotonMomentum.z() < 0.0) &&
813 if (DistanceToWall < DistanceToFloor) {
843 DistanceToWall =
sqrt(alpha * alpha - beta) - alpha;
848 closest1 = (closest.x()*closest.x()+closest.y()*closest.y())/
fDomeRadiusSq +
850 if (closest1 < 1. ) HitPMT += 1;
855 closest2 = (closest.x()*closest.x()+closest.y()*closest.y())/
fDomeRadiusSq +
857 if (closest2 < 1. ) HitPMT += 2;
862 closest3 = (closest.x()*closest.x()+closest.y()*closest.y())/
fDomeRadiusSq +
864 if (closest3 < 1. ) HitPMT += 4;
868 DistanceToPMT = 1.0e99;
881 if (DistanceToPMT1 < DistanceToPMT2) {
883 DistanceToPMT = DistanceToPMT1;
887 DistanceToPMT = DistanceToPMT2;
897 if (DistanceToPMT1 < DistanceToPMT3) {
899 DistanceToPMT = DistanceToPMT1;
903 DistanceToPMT = DistanceToPMT3;
909 if (DistanceToPMT2 < DistanceToPMT3) {
911 DistanceToPMT = DistanceToPMT2;
915 DistanceToPMT = DistanceToPMT3;
920 WARNING(
"Error determining next photon intersection in PropagateInTank()");
928 if (DistanceToPMT < DistanceToWall) {
929 if (DistanceToPMT < DistanceToRoof) {
931 Distance = DistanceToPMT;
935 Distance = DistanceToRoof;
939 if (DistanceToRoof < DistanceToWall) {
941 Distance = DistanceToRoof;
945 Distance = DistanceToWall;
949 rand = G4UniformRand();
950 TestVal = 1.0 - exp(-Distance *
fInvMFP);
951 if (rand < TestVal) {
957 DistanceTravelled = -log(1.0 - (rand / fRayleighFrac)) /
fInvMFP;
961 if ((fPhotonMomentum.z() < 0.0) &&
983 Dead = TransitionToDome<1>(
INWARD);
987 Dead = TransitionToDome<2>(
INWARD);
991 Dead = TransitionToDome<3>(
INWARD);
995 WARNING(
"Error finding target in PropagateInTank");
1013 std::string err(
"Tank photon tracking ran into an impossible condition");
1027 G4ThreeVector Alpha,
Beta, Delta, Normal;
1028 G4bool reflected, Dead;
1029 G4double n, n2, Transmission, VDotN;
1030 G4double ParaComp, PerpComp, ParaMag, PerpMag, X;
1031 G4ThreeVector ParaPolarization, PerpPolarization;
1036 Dead = PropogateInDome<pmtId>(flag);
1037 if (Dead)
return true;
1052 Normal /= Normal.mag();
1054 if (VDotN > 0.999999) {
1055 Transmission = 4.0 * n * n2 /
pow((n + n2), 2);
1056 reflected = G4UniformRand() > Transmission;
1065 Dead = PropogateInDome<pmtId>(flag);
1066 if (Dead)
return true;
1073 Dead = PropogateInDome<pmtId>(flag);
1074 if (Dead)
return true;
1079 Alpha /= Alpha.mag();
1080 X = (n2 * n2) - (n * n) * (1.0 - (VDotN * VDotN));
1081 if (X <= 0.0) X = 0.0;
1083 if (VDotN > 0.0) X = -
sqrt(X);
1089 PerpComp = PerpMag / (n * VDotN - X);
1090 ParaComp = ParaMag / (n2 * VDotN - (n * X / n2));
1091 Transmission = -(4.0 * n * VDotN * X) * (PerpComp * PerpComp +
1092 ParaComp * ParaComp);
1093 reflected = (G4UniformRand() >= Transmission);
1094 if (X == 0.0) reflected =
true;
1115 Dead = PropogateInDome<pmtId>(flag);
1116 if (Dead)
return true;
1128 Dead = PropogateInDome<pmtId>(flag);
1129 if (Dead)
return true;
1156 Dead = TransitionToInterface<pmtId>(flag);
1157 if (Dead)
return true;
1160 G4double DistanceThis, DistanceOther, DistanceToRoof;
1164 if (DistanceToRoof < 0.0) DistanceToRoof = 1.0e99;
1169 if (DistanceThis < DistanceOther) {
1170 if (DistanceToRoof < DistanceThis)
return true;
1171 Dead = (G4UniformRand() > exp(-DistanceThis /
1173 if (Dead)
return true;
1180 if (DistanceToRoof < DistanceOther)
return true;
1181 Dead = (G4UniformRand() > exp(-DistanceOther /
1183 if (Dead)
return true;
1186 Dead = TransitionToInterface<pmtId>(flag);
1187 if (Dead)
return true;
1192 if (DistanceToRoof < DistanceOther)
return true;
1193 Dead = (G4UniformRand() > exp(-DistanceOther /
1195 if (Dead)
return true;
1207 G4ThreeVector Alpha,
Beta, Delta, Normal;
1208 G4bool reflected, Dead;
1209 G4double n, n2, Transmission, VDotN;
1210 G4double ParaComp, PerpComp, ParaMag, PerpMag, X;
1211 G4ThreeVector ParaPolarization, PerpPolarization;
1217 Dead = PropogateInInterface<pmtId>(flag);
1218 if (Dead)
return true;
1233 Normal /= Normal.mag();
1235 if (VDotN > 0.999999) {
1236 Transmission = 4.0 * n * n2 /
pow((n + n2), 2);
1237 reflected = G4UniformRand() > Transmission;
1246 Dead = PropogateInInterface<pmtId>(flag);
1247 if (Dead)
return true;
1250 if (flag ==
OUTWARD)
return true;
1251 Dead = PropogateInInterface<pmtId>(flag);
1252 if (Dead)
return true;
1257 Alpha /= Alpha.mag();
1258 X = (n2 * n2) - (n * n) * (1.0 - (VDotN * VDotN));
1259 if (X <= 0.0) X = 0.0;
1261 if (VDotN > 0.0) X = -
sqrt(X);
1267 PerpComp = PerpMag / (n * VDotN - X);
1268 ParaComp = ParaMag / (n2 * VDotN - (n * X / n2));
1269 Transmission = -(4.0 * n * VDotN * X) * (PerpComp * PerpComp +
1270 ParaComp * ParaComp);
1271 reflected = (G4UniformRand() >= Transmission);
1272 if (X == 0.0) reflected =
true;
1292 Dead = PropogateInInterface<pmtId>(flag);
1293 if (Dead)
return true;
1305 Dead = PropogateInInterface<pmtId>(flag);
1306 if (Dead)
return true;
1327 G4double DistanceThis, DistanceOther, DistanceToRoof;
1329 if (DistanceToRoof < 0.0) DistanceToRoof = 1.0e99;
1336 if (DistanceThis < DistanceOther) {
1337 if (DistanceToRoof < DistanceThis)
return true;
1338 Dead = (G4UniformRand() > exp(-DistanceThis /
1340 if (Dead)
return true;
1347 if (DistanceToRoof < DistanceOther)
return true;
1348 Dead = (G4UniformRand() > exp(-DistanceOther /
1350 if (Dead)
return true;
1365 G4ThreeVector Normal(0.0, 0.0, -1.0);
1367 G4double r = G4UniformRand();
1368 if (r > Reflectivity)
return true;
1391 G4ThreeVector Normal;
1393 G4double r = G4UniformRand();
1394 if (r > Reflectivity)
return true;
1398 G4double W = 1.0 /
sqrt((X * X) + (Y * Y));
1399 Normal.set(-X * W, -Y * W, 0.0);
1421 G4ThreeVector Normal(0.0, 0.0, 1.0);
1423 G4double r = G4UniformRand();
1424 if (r > Reflectivity)
return true;
1456 G4double rand = G4UniformRand();
1457 G4double cosTheta =
sqrt(1.0 - rand);
1458 G4double sinTheta =
sqrt(rand);
1459 G4double Phi = 2.0 *
utl::kPi * G4UniformRand();
1460 G4double sinThetaCosPhi = sinTheta * cos(Phi);
1461 G4double sinThetaSinPhi = sinTheta * sin(Phi);
1462 G4double X = Normal.x();
1463 G4double Y = Normal.y();
1464 G4double W =
sqrt((X * X) + (Y * Y));
1465 G4double Vx = (X * cosTheta) - (Y * sinThetaSinPhi / W);
1466 G4double Vy = (Y * cosTheta) + (X * sinThetaSinPhi / W);
1467 G4double Vz = -W * sinThetaCosPhi;
1478 G4double rand = G4UniformRand();
1479 G4double cosTheta =
sqrt(1.0 - rand);
1480 G4double sinTheta =
sqrt(rand);
1481 G4double Phi = 2.0 *
utl::kPi * G4UniformRand();
1482 G4double Vx = sinTheta * cos(Phi);
1483 G4double Vy = sinTheta * sin(Phi);
1484 G4double Vz = Normal.z() * cosTheta;
1498 fPhotonMomentum /= fPhotonMomentum.mag();
1505 G4double Alpha, Phi;
1506 G4ThreeVector TrialMomentum;
1507 G4ThreeVector FacetNormal;
1508 G4double DotProduct;
1512 G4double sinAlpha, cosAlpha, sinAlphaSinPhi, sinAlphaCosPhi;
1513 G4double W, X, Y, Vx, Vy, Vz;
1518 sinAlpha = sin(Alpha);
1519 }
while (((G4UniformRand()*f_max) > sinAlpha) || (Alpha >= (0.5 *
utl::kPi)));
1520 Phi = 2.0 *
utl::kPi * G4UniformRand();
1521 cosAlpha = cos(Alpha);
1522 sinAlphaSinPhi = sinAlpha * sin(Phi);
1523 sinAlphaCosPhi = sinAlpha * cos(Phi);
1526 W =
sqrt((X * X) + (Y * Y));
1527 Vx = (X * cosAlpha) - (Y * sinAlphaSinPhi / W);
1528 Vy = (Y * cosAlpha) + (X * sinAlphaSinPhi / W);
1529 Vz = - W * sinAlphaCosPhi;
1530 FacetNormal.set(Vx, Vy, Vz);
1532 }
while (DotProduct >= 0.0);
1534 }
while (TrialMomentum.dot(Normal) <= 0.0);
1539 fPhotonMomentum /= fPhotonMomentum.mag();
1546 G4double Alpha, Phi;
1547 G4ThreeVector TrialMomentum;
1548 G4ThreeVector FacetNormal;
1549 G4double DotProduct;
1551 G4double sinAlpha, cosAlpha;
1552 G4double Vx, Vy, Vz;
1557 sinAlpha = sin(Alpha);
1558 }
while (((G4UniformRand()*f_max) > sinAlpha) || (Alpha >= (0.5 *
utl::kPi)));
1560 Phi = 2.0 *
utl::kPi * G4UniformRand();
1561 cosAlpha = cos(Alpha);
1562 Vx = sinAlpha * cos(Phi);
1563 Vy = sinAlpha * sin(Phi);
1564 Vz = Normal.z() * cosAlpha;
1565 FacetNormal.set(Vx, Vy, Vz);
1567 }
while (DotProduct >= 0.0);
1570 }
while (TrialMomentum.dot(Normal) <= 0.0);
1575 fPhotonMomentum /= fPhotonMomentum.mag();
1589 G4double DistA, DistB;
1592 c = Pos.dot(Pos) - (r * r);
1594 if (d < 0.0)
return 1.0e99;
1599 if (DistB < DistA) {
1600 if(DistB > 0.0)
return DistB;
1606 if (DistB > 0.0)
return DistB;
1613 const G4double r1,
const G4double r2)
1616 G4double a1, a2,
b[3],
c[3], d[3], e, f,
g;
1626 c[0] = Pos.x()*Pos.x();
1627 c[1] = Pos.y()*Pos.y();
1628 c[2] = Pos.z()*Pos.z();
1633 e = (b[0]+b[1])/(r1*r1) + b[2]/(r2*r2);
1634 f = 2.*((d[0]+d[1])/(r1*r1) + d[2]/(r2*r2));
1635 g = (c[0]+c[1])/(r1*r1)+c[2]/(r2*r2) - 1.;
1638 if ( (f*f-4*e*g) < 0 ) {
1642 a1 = 1./(2*e) * ( -f +
sqrt(f*f-4*e*g) );
1643 a2 = 1./(2*e) * ( -f -
sqrt(f*f-4*e*g) );
void LobeScatterVertical(const G4ThreeVector &)
G4ThreeVector fPhotonPolarization
unsigned int GetNPoints() const
G4bool fTrackSecondariesFirst
static double fPMTRadiuszSq
static double fPMTRadiusz
static double fPMTRadiusSq
Detector description interface for Station-related data.
G4bool TransitionToDome(G4int)
G4double GetEllipsoidIntersect(const G4ThreeVector &, const G4double, const G4double) const
static double fTankRadius
static utl::TabulatedFunction fLinerBACKSCATTERCONSTANT
static double fDomeRadiusSq
ArrayIterator XEnd()
end of array of X
CoordinateSystemPtr GetCoordinateSystem() const
Get the coordinate system of the current internal representation.
static utl::TabulatedFunction fLinerBackscatter
Class to hold collection (x,y) points and provide interpolation between them.
static double fTankHeight
static double fInterfaceRadiuszSq
static utl::TabulatedFunction fInterfaceABSORPTION
void SetTrackSecondariesFirst(const G4bool)
G4double GetAverageNumberOfPhotons(const G4DynamicParticle *, const G4Material *, const G4MaterialPropertyVector *) const
static double fInterfaceRadius
static double fInterfaceRzmax
G4ThreeVector fPhotonMomentum
static double fInterfaceRadiusSq
static double fTankRadius
const PMT & GetPMT(const int id) const
Get specified PMT by id.
static double fTankHalfHeight
double pow(const double x, const unsigned int i)
G4double GetContinuousStepLimit(const G4Track &, G4double, G4double, G4double &)
G4PhysicsTable * fThePhysicsTable
G4XTankFastCerenkov(const G4String &processName="Cerenkov")
static utl::TabulatedFunction fDomeAbsLength
Exception for reporting variable out of valid range.
void PropogateInTank(G4int)
static const sdet::Station * GetCurrentDetectorStation()
static utl::TabulatedFunction fLinerReflectivity
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
static double fTankHalfHeight
double GetCollectionEfficiency() const
Collection efficiency.
static utl::TabulatedFunction fInterfaceRIndex
static double fDomeRadius
static double fTankRadiusSq
double GetX(const CoordinateSystemPtr &coordinateSystem) const
static void GetDataFromConstruction()
static utl::TabulatedFunction fInterfaceRINDEX
static utl::TabulatedFunction fLinerSpecularSpike
void LobeScatterHorizontal(const G4ThreeVector &)
double Beta(const double energy)
Calculate the electron energy versus the relativistic beta.
static G4ThreeVector fPMTPos[4]
void AddPhoton(const int nPMT, const double peTime)
static utl::TabulatedFunction fPmtdomeABSORPTION
static G4XTankPMT * fgPMTAction
#define WARNING(message)
Macro for logging warning messages.
G4double GetSphereIntersect(const G4ThreeVector &, const G4double) const
static utl::TabulatedFunction fWaterAbsLength
static double fInterfaceRadiusz
G4PhysicsTable * GetPhysicsTable() const
void SetMaxNumPhotonsPerStep(const G4int)
static utl::TabulatedFunction fLinerSpecularLobe
G4bool PropogateInDome(G4int &)
static double fDomeRadiusz
G4bool TransitionToInterface(G4int &)
ArrayIterator YBegin()
begin of array of Y
static utl::TabulatedFunction fDomeRIndex
static utl::TabulatedFunction fPmtdomeRINDEX
double GetY(const CoordinateSystemPtr &coordinateSystem) const
static utl::TabulatedFunction fLinerREFLECTIVITY
double Distance(const Point &p, const sdet::Station &s)
static utl::TabulatedFunction fLinerSPECULARSPIKECONSTANT
static utl::TabulatedFunction fQE
static double fSIGMA_ALPHA
G4bool IsApplicable(const G4ParticleDefinition &)
void BuildThePhysicsTable()
G4VParticleChange * AlongStepDoIt(const G4Track &, const G4Step &)
static utl::TabulatedFunction fWaterABSORPTION
ArrayIterator XBegin()
begin of array of X
static G4double fRoofPos[4]
const utl::TabulatedFunction & GetQuantumEfficiency() const
Quantum efficiency.
void SpikeScatter(const G4ThreeVector &)
G4bool PropogateInInterface(G4int &)
static double fDomeRadiuszSq
static double fTankThickness
G4double fSampledMomentum
static double fInterfaceRmax
ArrayIterator YEnd()
end of array of Y
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
static utl::TabulatedFunction fLinerSPECULARLOBECONSTANT
#define ERROR(message)
Macro for logging error messages.
void DiffuseScatterVertical(const G4ThreeVector &)
void DiffuseScatterHorizontal(const G4ThreeVector &)
G4ThreeVector fPhotonPosition
static double fTankThickness
void DumpPhysicsTable() const
static double fSigmaAlpha
static utl::TabulatedFunction fInterfaceAbsLength