32 using namespace G4TankSimulatorASCII;
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) {
257 const bool IsFromMuonDecay= aStep.GetTrack()->GetUserInformation();
261 aParticleChange.Initialize(aTrack);
262 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
263 const G4Material* aMaterial = aTrack.GetMaterial();
264 G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint();
265 G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
267 const G4ThreeVector x0 = pPreStepPoint->GetPosition();
268 const G4ThreeVector p0 = aStep.GetDeltaPosition().unit();
269 const G4double t0 = pPreStepPoint->GetGlobalTime();
271 if (t0 > 1.0e6)
return G4VContinuousProcess::AlongStepDoIt(aTrack, aStep);
273 G4ThreeVector aPrimaryDirection = pPreStepPoint->GetMomentumDirection();
275 const G4double cosAlpha = aPrimaryDirection.z();
276 const G4double sinAlpha =
sqrt(1.0 - (cosAlpha * cosAlpha));
277 const G4double cosBeta = aPrimaryDirection.x() / sinAlpha;
278 const G4double sinBeta = aPrimaryDirection.y() / sinAlpha;
280 G4MaterialPropertiesTable* aMaterialPropertiesTable =
281 aMaterial->GetMaterialPropertiesTable();
283 if (!aMaterialPropertiesTable)
284 return G4VContinuousProcess::AlongStepDoIt(aTrack, aStep);
286 const G4MaterialPropertyVector* Rindex =
287 aMaterialPropertiesTable->GetProperty(
"RINDEX");
290 return G4VContinuousProcess::AlongStepDoIt(aTrack, aStep);
294 if (MeanNumPhotons <= 0.0) {
295 aParticleChange.SetNumberOfSecondaries(0);
296 return G4VContinuousProcess::AlongStepDoIt(aTrack, aStep);
299 MeanNumPhotons *= aStep.GetStepLength();
301 G4int NumPhotons =
static_cast<G4int
>(G4Poisson(MeanNumPhotons));
305 aParticleChange.SetNumberOfSecondaries(0);
307 return G4VContinuousProcess::AlongStepDoIt(aTrack, aStep);
309 #if (G4VERSION_NUMBER < 920)
310 const G4double Pmin = Rindex->GetMinPhotonMomentum();
311 const G4double Pmax = Rindex->GetMaxPhotonMomentum();
313 const G4double Pmin = Rindex->GetMinPhotonEnergy();
314 const G4double Pmax = Rindex->GetMaxPhotonEnergy();
317 const G4double dp = Pmax - Pmin;
318 const G4double nMax = Rindex->GetMaxProperty();
320 const G4double betaInverse = aParticle->GetTotalEnergy() /
321 aParticle->GetTotalMomentum();
323 const G4double maxCos = betaInverse / nMax;
324 const G4double maxSin2 = (1.0 - (maxCos * maxCos));
326 const double minQEMomentum =
fQE[0].X();
333 G4double rand, cosTheta, sin2Theta;
334 G4double phi, sinTheta, px, py, pz;
336 G4double delta, deltaTime;
337 G4double sinThetaSinPhi, sinThetaCosPhi;
339 double absorptionMFP;
341 for (G4int i = 0; i < NumPhotons; ++i) {
343 rand = G4UniformRand();
347 sin2Theta = (1.0 - (cosTheta * cosTheta));
348 rand = G4UniformRand();
349 }
while ((rand * maxSin2) > sin2Theta);
361 G4double SampledRI_Sq, RIConst;
364 int iFirstValidBin_Wat = 0;
375 RIConst = (SampledRI_Sq + 2.0) * (SampledRI_Sq - 1.0);
380 invSumMFP = 1.0 / (absorptionMFP + rayleighMFP);
382 fInvMFP = (1.0 / absorptionMFP) + (1.0 / rayleighMFP);
387 sinTheta =
sqrt(sin2Theta);
388 rand = G4UniformRand();
391 sinThetaSinPhi = sin(phi) * sinTheta;
392 sinThetaCosPhi = cos(phi) * sinTheta;
394 px = (cosAlpha * cosBeta * sinThetaCosPhi) - (sinBeta * sinThetaSinPhi)
395 + (cosBeta * sinAlpha * cosTheta);
396 py = (cosAlpha * sinBeta * sinThetaCosPhi) + (cosBeta * sinThetaSinPhi)
397 + (sinBeta * sinAlpha * cosTheta);
398 pz = (cosAlpha * cosTheta) - (sinAlpha * sinThetaCosPhi);
405 rand = G4UniformRand();
406 delta = rand * aStep.GetStepLength();
407 deltaTime = delta / ((pPreStepPoint->GetVelocity() +
408 pPostStepPoint->GetVelocity()) / 2.0);
421 if (verboseLevel > 0) {
422 G4cerr <<
"\n Exiting from G4Cerenkov::DoIt -- NumberOfSecondaries = "
423 << aParticleChange.GetNumberOfSecondaries() << G4endl;
426 return G4VContinuousProcess::AlongStepDoIt(aTrack, aStep);
438 const G4MaterialTable* theMaterialTable= G4Material::GetMaterialTable();
439 G4int numOfMaterials = G4Material::GetNumberOfMaterials();
442 G4PhysicsOrderedFreeVector *aPhysicsOrderedFreeVector;
443 G4Material *aMaterial;
444 G4MaterialPropertiesTable *aMaterialPropertiesTable;
445 G4MaterialPropertyVector *theRIndexVector;
446 G4double currentRI, currentPM, currentCAI;
447 G4double prevRI, prevPM, prevCAI;
449 for (G4int i = 0; i < numOfMaterials; ++i) {
451 aPhysicsOrderedFreeVector =
new G4PhysicsOrderedFreeVector();
452 aMaterial = (*theMaterialTable)[i];
453 aMaterialPropertiesTable = aMaterial->GetMaterialPropertiesTable();
455 if (aMaterialPropertiesTable) {
457 theRIndexVector = aMaterialPropertiesTable->GetProperty(
"RINDEX");
459 if (theRIndexVector) {
461 theRIndexVector->ResetIterator();
462 ++(*theRIndexVector);
463 currentRI = theRIndexVector->GetProperty();
465 if (currentRI > 1.0) {
467 #if (G4VERSION_NUMBER < 920)
468 currentPM = theRIndexVector->GetPhotonMomentum();
470 currentPM = theRIndexVector->GetPhotonEnergy();
474 aPhysicsOrderedFreeVector->InsertValues(currentPM , currentCAI);
477 prevCAI = currentCAI;
479 while(++(*theRIndexVector)) {
481 currentRI = theRIndexVector->GetProperty();
483 #if (G4VERSION_NUMBER < 920)
484 currentPM = theRIndexVector->GetPhotonMomentum();
486 currentPM = theRIndexVector->GetPhotonEnergy();
489 currentCAI = 0.5 * ((1.0 / (prevRI * prevRI)) +
490 (1.0 / (currentRI * currentRI)));
491 currentCAI = prevCAI + ((currentPM - prevPM) * currentCAI);
492 aPhysicsOrderedFreeVector->InsertValues(currentPM, currentCAI);
494 prevCAI = currentCAI;
513 G4double, G4double, G4double &) {
518 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
519 const G4Material* aMaterial = aTrack.GetMaterial();
521 G4MaterialPropertiesTable* aMaterialPropertiesTable =
522 aMaterial->GetMaterialPropertiesTable();
524 if (!aMaterialPropertiesTable)
527 const G4MaterialPropertyVector* Rindex =
528 aMaterialPropertiesTable->GetProperty(
"RINDEX");
535 if (meanNumPhotons <= 0.0)
545 const G4Material* aMaterial,
546 const G4MaterialPropertyVector* Rindex)
const {
547 const G4double Rfact = 369.81 / (
eV *
cm);
549 if (aParticle->GetTotalMomentum() <= 0.0)
552 G4double betaInverse = aParticle->GetTotalEnergy() /
553 aParticle->GetTotalMomentum();
555 G4int materialIndex = aMaterial->GetIndex();
557 G4PhysicsOrderedFreeVector* CerenkovAngleIntegrals =
560 if (!(CerenkovAngleIntegrals->IsFilledVectorExist()))
563 #if (G4VERSION_NUMBER < 920)
564 G4double Pmin = Rindex->GetMinPhotonMomentum();
565 G4double Pmax = Rindex->GetMaxPhotonMomentum();
567 G4double Pmin = Rindex->GetMinPhotonEnergy();
568 G4double Pmax = Rindex->GetMaxPhotonEnergy();
571 G4double nMin = Rindex->GetMinProperty();
572 G4double nMax = Rindex->GetMaxProperty();
573 G4double CAImax = CerenkovAngleIntegrals->GetMaxValue();
576 if (nMax < betaInverse) {
581 }
else if (nMin > betaInverse) {
588 #if (G4VERSION_NUMBER < 920)
589 Pmin = Rindex->GetPhotonMomentum(betaInverse);
591 Pmin = Rindex->GetPhotonEnergy(betaInverse);
595 G4double CAImin = CerenkovAngleIntegrals->GetValue(Pmin, isOutRange);
596 ge = CAImax - CAImin;
598 if (verboseLevel>0) {
599 G4cerr <<
"CAImin = " << CAImin << G4endl;
600 G4cerr <<
"ge = " << ge << G4endl;
605 G4double charge = aParticle->GetDefinition()->GetPDGCharge();
606 G4double numPhotons = Rfact *
pow((charge /
eplus), 2) *
607 (dp - ge * betaInverse*betaInverse);
620 const G4double rand = 2.0 * G4UniformRand() - 1.0;
621 const G4double cosTheta= (rand < 0.0)?
622 (-
pow(-rand, 1.0 / 3.0)):
pow(rand, 1.0 / 3.0);
623 const G4double sinTheta =
sqrt(1.0 - cosTheta * cosTheta);
624 const G4double phi = 2.0 *
utl::kPi * G4UniformRand();
625 const G4double cosPhi = cos(phi);
626 const G4double sinPhi = sin(phi);
630 const G4double k = 1.0 /
sqrt(1.0 - c * c);
631 const G4double R11 = k *
b;
632 const G4double R12 = k * a *
c;
633 const G4double R21 = -k *
a;
634 const G4double R22 = k * b *
c;
635 const G4double R32 = -1.0 / k;
643 if (G4UniformRand() < 0.5) {
645 x = sinTheta * cosPhi;
646 y = sinTheta * sinPhi;
649 (R21 * x + R22 * y + b * z),
651 x = cosTheta * cosPhi;
652 y = cosTheta * sinPhi;
655 (R21 * x + R22 * y + b * z),
660 x = sinTheta * cosPhi;
661 y = sinTheta * sinPhi;
664 (R21 * x + R22 * y + b * z),
666 x = -cosTheta * cosPhi;
667 y = -cosTheta * sinPhi;
671 (R21 * x + R22 * y + b * z),
702 G4ThreeVector displacement;
705 for(
unsigned int i=1; i<4; ++i){
707 closest = (displacement.x()*displacement.x()+displacement.y()*displacement.y())/
fDomeRadiusSq +
710 closest = (displacement.x()*displacement.x()+displacement.y()*displacement.y())/
fInterfaceRadiusSq +
713 closest = (displacement.x()*displacement.x()+displacement.y()*displacement.y())/
fPMTRadiusSq +
715 if (closest < 1. && -displacement.z() >
fHeightz ) {
737 Dead = TransitionToDome<1>(flag);
742 Dead = TransitionToDome<2>(flag);
747 Dead = TransitionToDome<3>(flag);
755 G4double DistanceToFloor, DistanceToWall, DistanceTravelled,
Distance;
756 G4double DistanceToRoof, DistanceToPMT1, DistanceToPMT2, DistanceToPMT3;
757 G4double alpha, beta, gamma;
760 G4double closest1, closest2, closest3;
761 G4ThreeVector closest, Displacement1, Displacement2, Displacement3;
762 G4double DotProduct, rand, DistanceToPMT;
763 G4int HitPMT, TargetPMT = -1, Target;
771 WARNING(
"The z component of the momentul is 0, skipping photon.");
785 const double distance=alpha * alpha - beta;
787 WARNING(
"Distance to wall is not finite, skipping photon");
791 DistanceToWall =
sqrt(distance) - alpha;
794 rand = G4UniformRand();
795 TestVal=(DistanceToWall < DistanceToFloor)?
796 (1.0 - exp(-DistanceToWall *
fInvMFP)):(1.0 - exp(-DistanceToFloor * fInvMFP));
798 if (rand < TestVal) {
802 DistanceTravelled = -log(1.0 - (rand / fRayleighFrac)) /
fInvMFP;
806 if ((fPhotonMomentum.z() < 0.0) &&
817 if (DistanceToWall < DistanceToFloor) {
847 DistanceToWall =
sqrt(alpha * alpha - beta) - alpha;
852 closest1 = (closest.x()*closest.x()+closest.y()*closest.y())/
fDomeRadiusSq +
854 if (closest1 < 1. ) HitPMT += 1;
859 closest2 = (closest.x()*closest.x()+closest.y()*closest.y())/
fDomeRadiusSq +
861 if (closest2 < 1. ) HitPMT += 2;
866 closest3 = (closest.x()*closest.x()+closest.y()*closest.y())/
fDomeRadiusSq +
868 if (closest3 < 1. ) HitPMT += 4;
872 DistanceToPMT = 1.0e99;
885 if (DistanceToPMT1 < DistanceToPMT2) {
887 DistanceToPMT = DistanceToPMT1;
891 DistanceToPMT = DistanceToPMT2;
901 if (DistanceToPMT1 < DistanceToPMT3) {
903 DistanceToPMT = DistanceToPMT1;
907 DistanceToPMT = DistanceToPMT3;
913 if (DistanceToPMT2 < DistanceToPMT3) {
915 DistanceToPMT = DistanceToPMT2;
919 DistanceToPMT = DistanceToPMT3;
924 WARNING(
"Error determining next photon intersection in PropagateInTank()");
932 if (DistanceToPMT < DistanceToWall) {
933 if (DistanceToPMT < DistanceToRoof) {
935 Distance = DistanceToPMT;
939 Distance = DistanceToRoof;
943 if (DistanceToRoof < DistanceToWall) {
945 Distance = DistanceToRoof;
949 Distance = DistanceToWall;
953 rand = G4UniformRand();
954 TestVal = 1.0 - exp(-Distance *
fInvMFP);
955 if (rand < TestVal) {
961 DistanceTravelled = -log(1.0 - (rand / fRayleighFrac)) /
fInvMFP;
965 if ((fPhotonMomentum.z() < 0.0) &&
987 Dead = TransitionToDome<1>(
INWARD);
991 Dead = TransitionToDome<2>(
INWARD);
995 Dead = TransitionToDome<3>(
INWARD);
999 WARNING(
"Error finding target in PropagateInTank");
1017 std::string err(
"Tank photon tracking ran into an impossible condition");
1031 G4ThreeVector Alpha,
Beta, Delta, Normal;
1032 G4bool reflected, Dead;
1033 G4double n, n2, Transmission, VDotN;
1034 G4double ParaComp, PerpComp, ParaMag, PerpMag, X;
1035 G4ThreeVector ParaPolarization, PerpPolarization;
1040 Dead = PropogateInDome<pmtId>(flag);
1041 if (Dead)
return true;
1056 Normal /= Normal.mag();
1058 if (VDotN > 0.999999) {
1059 Transmission = 4.0 * n * n2 /
pow((n + n2), 2);
1060 reflected = G4UniformRand() > Transmission;
1069 Dead = PropogateInDome<pmtId>(flag);
1070 if (Dead)
return true;
1077 Dead = PropogateInDome<pmtId>(flag);
1078 if (Dead)
return true;
1083 Alpha /= Alpha.mag();
1084 X = (n2 * n2) - (n * n) * (1.0 - (VDotN * VDotN));
1085 if (X <= 0.0) X = 0.0;
1087 if (VDotN > 0.0) X = -
sqrt(X);
1093 PerpComp = PerpMag / (n * VDotN - X);
1094 ParaComp = ParaMag / (n2 * VDotN - (n * X / n2));
1095 Transmission = -(4.0 * n * VDotN * X) * (PerpComp * PerpComp +
1096 ParaComp * ParaComp);
1097 reflected = (G4UniformRand() >= Transmission);
1098 if (X == 0.0) reflected =
true;
1119 Dead = PropogateInDome<pmtId>(flag);
1120 if (Dead)
return true;
1132 Dead = PropogateInDome<pmtId>(flag);
1133 if (Dead)
return true;
1160 Dead = TransitionToInterface<pmtId>(flag);
1161 if (Dead)
return true;
1164 G4double DistanceThis, DistanceOther, DistanceToRoof;
1168 if (DistanceToRoof < 0.0) DistanceToRoof = 1.0e99;
1173 if (DistanceThis < DistanceOther) {
1174 if (DistanceToRoof < DistanceThis)
return true;
1175 Dead = (G4UniformRand() > exp(-DistanceThis /
1177 if (Dead)
return true;
1184 if (DistanceToRoof < DistanceOther)
return true;
1185 Dead = (G4UniformRand() > exp(-DistanceOther /
1187 if (Dead)
return true;
1190 Dead = TransitionToInterface<pmtId>(flag);
1191 if (Dead)
return true;
1196 if (DistanceToRoof < DistanceOther)
return true;
1197 Dead = (G4UniformRand() > exp(-DistanceOther /
1199 if (Dead)
return true;
1211 G4ThreeVector Alpha,
Beta, Delta, Normal;
1212 G4bool reflected, Dead;
1213 G4double n, n2, Transmission, VDotN;
1214 G4double ParaComp, PerpComp, ParaMag, PerpMag, X;
1215 G4ThreeVector ParaPolarization, PerpPolarization;
1221 Dead = PropogateInInterface<pmtId>(flag);
1222 if (Dead)
return true;
1237 Normal /= Normal.mag();
1239 if (VDotN > 0.999999) {
1240 Transmission = 4.0 * n * n2 /
pow((n + n2), 2);
1241 reflected = G4UniformRand() > Transmission;
1250 Dead = PropogateInInterface<pmtId>(flag);
1251 if (Dead)
return true;
1254 if (flag ==
OUTWARD)
return true;
1255 Dead = PropogateInInterface<pmtId>(flag);
1256 if (Dead)
return true;
1261 Alpha /= Alpha.mag();
1262 X = (n2 * n2) - (n * n) * (1.0 - (VDotN * VDotN));
1263 if (X <= 0.0) X = 0.0;
1265 if (VDotN > 0.0) X = -
sqrt(X);
1271 PerpComp = PerpMag / (n * VDotN - X);
1272 ParaComp = ParaMag / (n2 * VDotN - (n * X / n2));
1273 Transmission = -(4.0 * n * VDotN * X) * (PerpComp * PerpComp +
1274 ParaComp * ParaComp);
1275 reflected = (G4UniformRand() >= Transmission);
1276 if (X == 0.0) reflected =
true;
1296 Dead = PropogateInInterface<pmtId>(flag);
1297 if (Dead)
return true;
1309 Dead = PropogateInInterface<pmtId>(flag);
1310 if (Dead)
return true;
1331 G4double DistanceThis, DistanceOther, DistanceToRoof;
1333 if (DistanceToRoof < 0.0) DistanceToRoof = 1.0e99;
1340 if (DistanceThis < DistanceOther) {
1341 if (DistanceToRoof < DistanceThis)
return true;
1342 Dead = (G4UniformRand() > exp(-DistanceThis /
1344 if (Dead)
return true;
1351 if (DistanceToRoof < DistanceOther)
return true;
1352 Dead = (G4UniformRand() > exp(-DistanceOther /
1354 if (Dead)
return true;
1369 G4ThreeVector Normal(0.0, 0.0, -1.0);
1371 G4double r = G4UniformRand();
1372 if (r > Reflectivity)
return true;
1395 G4ThreeVector Normal;
1397 G4double r = G4UniformRand();
1398 if (r > Reflectivity)
return true;
1402 G4double W = 1.0 /
sqrt((X * X) + (Y * Y));
1403 Normal.set(-X * W, -Y * W, 0.0);
1425 G4ThreeVector Normal(0.0, 0.0, 1.0);
1427 G4double r = G4UniformRand();
1428 if (r > Reflectivity)
return true;
1460 G4double rand = G4UniformRand();
1461 G4double cosTheta =
sqrt(1.0 - rand);
1462 G4double sinTheta =
sqrt(rand);
1463 G4double Phi = 2.0 *
utl::kPi * G4UniformRand();
1464 G4double sinThetaCosPhi = sinTheta * cos(Phi);
1465 G4double sinThetaSinPhi = sinTheta * sin(Phi);
1466 G4double X = Normal.x();
1467 G4double Y = Normal.y();
1468 G4double W =
sqrt((X * X) + (Y * Y));
1469 G4double Vx = (X * cosTheta) - (Y * sinThetaSinPhi / W);
1470 G4double Vy = (Y * cosTheta) + (X * sinThetaSinPhi / W);
1471 G4double Vz = -W * sinThetaCosPhi;
1482 G4double rand = G4UniformRand();
1483 G4double cosTheta =
sqrt(1.0 - rand);
1484 G4double sinTheta =
sqrt(rand);
1485 G4double Phi = 2.0 *
utl::kPi * G4UniformRand();
1486 G4double Vx = sinTheta * cos(Phi);
1487 G4double Vy = sinTheta * sin(Phi);
1488 G4double Vz = Normal.z() * cosTheta;
1502 fPhotonMomentum /= fPhotonMomentum.mag();
1509 G4double Alpha, Phi;
1510 G4ThreeVector TrialMomentum;
1511 G4ThreeVector FacetNormal;
1512 G4double DotProduct;
1516 G4double sinAlpha, cosAlpha, sinAlphaSinPhi, sinAlphaCosPhi;
1517 G4double W, X, Y, Vx, Vy, Vz;
1522 sinAlpha = sin(Alpha);
1523 }
while (((G4UniformRand()*f_max) > sinAlpha) || (Alpha >= (0.5 *
utl::kPi)));
1524 Phi = 2.0 *
utl::kPi * G4UniformRand();
1525 cosAlpha = cos(Alpha);
1526 sinAlphaSinPhi = sinAlpha * sin(Phi);
1527 sinAlphaCosPhi = sinAlpha * cos(Phi);
1530 W =
sqrt((X * X) + (Y * Y));
1531 Vx = (X * cosAlpha) - (Y * sinAlphaSinPhi / W);
1532 Vy = (Y * cosAlpha) + (X * sinAlphaSinPhi / W);
1533 Vz = - W * sinAlphaCosPhi;
1534 FacetNormal.set(Vx, Vy, Vz);
1536 }
while (DotProduct >= 0.0);
1538 }
while (TrialMomentum.dot(Normal) <= 0.0);
1543 fPhotonMomentum /= fPhotonMomentum.mag();
1550 G4double Alpha, Phi;
1551 G4ThreeVector TrialMomentum;
1552 G4ThreeVector FacetNormal;
1553 G4double DotProduct;
1555 G4double sinAlpha, cosAlpha;
1556 G4double Vx, Vy, Vz;
1561 sinAlpha = sin(Alpha);
1562 }
while (((G4UniformRand()*f_max) > sinAlpha) || (Alpha >= (0.5 *
utl::kPi)));
1564 Phi = 2.0 *
utl::kPi * G4UniformRand();
1565 cosAlpha = cos(Alpha);
1566 Vx = sinAlpha * cos(Phi);
1567 Vy = sinAlpha * sin(Phi);
1568 Vz = Normal.z() * cosAlpha;
1569 FacetNormal.set(Vx, Vy, Vz);
1571 }
while (DotProduct >= 0.0);
1574 }
while (TrialMomentum.dot(Normal) <= 0.0);
1579 fPhotonMomentum /= fPhotonMomentum.mag();
1593 G4double DistA, DistB;
1596 c = Pos.dot(Pos) - (r * r);
1598 if (d < 0.0)
return 1.0e99;
1603 if (DistB < DistA) {
1604 if(DistB > 0.0)
return DistB;
1610 if (DistB > 0.0)
return DistB;
1617 const G4double r1,
const G4double r2)
1620 G4double a1, a2,
b[3],
c[3], d[3], e, f,
g;
1630 c[0] = Pos.x()*Pos.x();
1631 c[1] = Pos.y()*Pos.y();
1632 c[2] = Pos.z()*Pos.z();
1637 e = (b[0]+b[1])/(r1*r1) + b[2]/(r2*r2);
1638 f = 2.*((d[0]+d[1])/(r1*r1) + d[2]/(r2*r2));
1639 g = (c[0]+c[1])/(r1*r1)+c[2]/(r2*r2) - 1.;
1642 if ( (f*f-4*e*g) < 0 ) {
1646 a1 = 1./(2*e) * ( -f +
sqrt(f*f-4*e*g) );
1647 a2 = 1./(2*e) * ( -f -
sqrt(f*f-4*e*g) );
static G4TankPMT * fgPMTAction
static double fInterfaceRadiusSq
unsigned int GetNPoints() const
static utl::TabulatedFunction fQE
static double fTankRadius
G4bool TransitionToInterface(G4int &)
Detector description interface for Station-related data.
static double fPMTRadiusz
static double fTankThickness
G4ThreeVector fPhotonPolarization
G4bool fPhotonIsFromMuonDecay
ArrayIterator XEnd()
end of array of X
static utl::TabulatedFunction fLinerSpecularLobe
CoordinateSystemPtr GetCoordinateSystem() const
Get the coordinate system of the current internal representation.
Class to hold collection (x,y) points and provide interpolation between them.
static double fInterfaceRzmax
G4VParticleChange * AlongStepDoIt(const G4Track &, const G4Step &)
static utl::TabulatedFunction fLinerSPECULARLOBECONSTANT
void LobeScatterVertical(const G4ThreeVector &)
static utl::TabulatedFunction fLinerBACKSCATTERCONSTANT
G4double fSampledMomentum
void SetTrackSecondariesFirst(const G4bool)
G4bool IsApplicable(const G4ParticleDefinition &)
const PMT & GetPMT(const int id) const
Get specified PMT by id.
G4double GetSphereIntersect(const G4ThreeVector &, const G4double) const
static double fPMTRadiuszSq
G4TankFastCerenkov(const G4String &processName="Cerenkov")
G4PhysicsTable * fThePhysicsTable
double pow(const double x, const unsigned int i)
static double fSIGMA_ALPHA
static utl::TabulatedFunction fLinerSpecularSpike
static double fDomeRadiusz
G4ThreeVector fPhotonMomentum
static utl::TabulatedFunction fWaterABSORPTION
Exception for reporting variable out of valid range.
G4bool PropogateInDome(G4int &)
void AddPhoton(const int nPMT, const double peTime, const bool IsFromMuonDecay)
void DiffuseScatterVertical(const G4ThreeVector &)
void BuildThePhysicsTable()
static const sdet::Station * GetCurrentDetectorStation()
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
static double fTankHalfHeight
double GetCollectionEfficiency() const
Collection efficiency.
static double fInterfaceRmax
static double fTankRadius
static utl::TabulatedFunction fInterfaceRIndex
double GetX(const CoordinateSystemPtr &coordinateSystem) const
G4bool TransitionToDome(G4int)
G4PhysicsTable * GetPhysicsTable() const
static utl::TabulatedFunction fInterfaceABSORPTION
G4double GetAverageNumberOfPhotons(const G4DynamicParticle *, const G4Material *, const G4MaterialPropertyVector *) const
static G4ThreeVector fPMTPos[4]
static double fInterfaceRadiusz
G4ThreeVector fPhotonPosition
static utl::TabulatedFunction fWaterAbsLength
double Beta(const double energy)
Calculate the electron energy versus the relativistic beta.
#define WARNING(message)
Macro for logging warning messages.
static double fTankHalfHeight
void SpikeScatter(const G4ThreeVector &)
static utl::TabulatedFunction fPmtdomeRINDEX
G4bool PropogateInInterface(G4int &)
ArrayIterator YBegin()
begin of array of Y
static double fDomeRadiuszSq
double GetY(const CoordinateSystemPtr &coordinateSystem) const
double Distance(const Point &p, const sdet::Station &s)
static double fTankRadiusSq
static utl::TabulatedFunction fDomeAbsLength
static double fPMTRadiusSq
static double fDomeRadiusSq
G4double GetContinuousStepLimit(const G4Track &, G4double, G4double, G4double &)
static double fTankThickness
static utl::TabulatedFunction fInterfaceAbsLength
ArrayIterator XBegin()
begin of array of X
const utl::TabulatedFunction & GetQuantumEfficiency() const
Quantum efficiency.
static double fInterfaceRadiuszSq
void DumpPhysicsTable() const
static utl::TabulatedFunction fLinerSPECULARSPIKECONSTANT
G4double GetEllipsoidIntersect(const G4ThreeVector &, const G4double, const G4double) const
static G4double fRoofPos[4]
G4bool fTrackSecondariesFirst
static double fDomeRadius
void LobeScatterHorizontal(const G4ThreeVector &)
void DiffuseScatterHorizontal(const G4ThreeVector &)
ArrayIterator YEnd()
end of array of Y
static utl::TabulatedFunction fDomeRIndex
static utl::TabulatedFunction fLinerReflectivity
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
static void GetDataFromConstruction()
static double fTankHeight
void PropogateInTank(G4int)
static double fInterfaceRadius
#define ERROR(message)
Macro for logging error messages.
static double fSigmaAlpha
void SetMaxNumPhotonsPerStep(const G4int)
static utl::TabulatedFunction fLinerBackscatter
static utl::TabulatedFunction fLinerREFLECTIVITY
static utl::TabulatedFunction fPmtdomeABSORPTION
static utl::TabulatedFunction fInterfaceRINDEX