00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00027
00028
00029
00030
00031
00032
00033
00034
00035
00037
00038
00039
00040
00041
00042
00043
00044
00046
00047
00048 #include "G4SPSPosDistribution.hh"
00049
00050 #include "G4PhysicalConstants.hh"
00051 #include "Randomize.hh"
00052 #include "G4TransportationManager.hh"
00053 #include "G4VPhysicalVolume.hh"
00054 #include "G4PhysicalVolumeStore.hh"
00055
00056 G4SPSPosDistribution::G4SPSPosDistribution()
00057 : posRndm(0)
00058 {
00059
00060
00061
00062
00063 SourcePosType = "Point";
00064 Shape = "NULL";
00065 halfx = 0.;
00066 halfy = 0.;
00067 halfz = 0.;
00068 Radius = 0.;
00069 Radius0 = 0.;
00070 SR = 0.;
00071 SX = 0.;
00072 SY = 0.;
00073 ParAlpha = 0.;
00074 ParTheta = 0.;
00075 ParPhi = 0.;
00076 CentreCoords = G4ThreeVector(0., 0., 0.);
00077 Rotx = CLHEP::HepXHat;
00078 Roty = CLHEP::HepYHat;
00079 Rotz = CLHEP::HepZHat;
00080 Confine = false;
00081 VolName = "NULL";
00082 SideRefVec1 = CLHEP::HepXHat;
00083 SideRefVec2 = CLHEP::HepYHat;
00084 SideRefVec3 = CLHEP::HepZHat;
00085 verbosityLevel = 0 ;
00086 gNavigator = G4TransportationManager::GetTransportationManager()
00087 ->GetNavigatorForTracking();
00088 }
00089
00090 G4SPSPosDistribution::~G4SPSPosDistribution()
00091 {
00092 }
00093
00094 void G4SPSPosDistribution::SetPosDisType(G4String PosType)
00095 {
00096 SourcePosType = PosType;
00097 }
00098
00099 void G4SPSPosDistribution::SetPosDisShape(G4String shapeType)
00100 {
00101 Shape = shapeType;
00102 }
00103
00104 void G4SPSPosDistribution::SetCentreCoords(G4ThreeVector coordsOfCentre)
00105 {
00106 CentreCoords = coordsOfCentre;
00107 }
00108
00109 void G4SPSPosDistribution::SetPosRot1(G4ThreeVector posrot1)
00110 {
00111
00112 Rotx = posrot1;
00113 if(verbosityLevel == 2)
00114 {
00115 G4cout << "Vector x' " << Rotx << G4endl;
00116 }
00117 GenerateRotationMatrices();
00118 }
00119
00120 void G4SPSPosDistribution::SetPosRot2(G4ThreeVector posrot2)
00121 {
00122
00123
00124 Roty = posrot2;
00125 if(verbosityLevel == 2)
00126 {
00127 G4cout << "The vector in the x'-y' plane " << Roty << G4endl;
00128 }
00129 GenerateRotationMatrices();
00130 }
00131
00132 void G4SPSPosDistribution::SetHalfX(G4double xhalf)
00133 {
00134 halfx = xhalf;
00135 }
00136
00137 void G4SPSPosDistribution::SetHalfY(G4double yhalf)
00138 {
00139 halfy = yhalf;
00140 }
00141
00142 void G4SPSPosDistribution::SetHalfZ(G4double zhalf)
00143 {
00144 halfz = zhalf;
00145 }
00146
00147 void G4SPSPosDistribution::SetRadius(G4double rds)
00148 {
00149 Radius = rds;
00150 }
00151
00152 void G4SPSPosDistribution::SetRadius0(G4double rds)
00153 {
00154 Radius0 = rds;
00155 }
00156
00157 void G4SPSPosDistribution::SetBeamSigmaInR(G4double r)
00158 {
00159 SX = SY = r;
00160 SR = r;
00161 }
00162
00163 void G4SPSPosDistribution::SetBeamSigmaInX(G4double r)
00164 {
00165 SX = r;
00166 }
00167
00168 void G4SPSPosDistribution::SetBeamSigmaInY(G4double r)
00169 {
00170 SY = r;
00171 }
00172
00173 void G4SPSPosDistribution::SetParAlpha(G4double paralp)
00174 {
00175 ParAlpha = paralp;
00176 }
00177
00178 void G4SPSPosDistribution::SetParTheta(G4double parthe)
00179 {
00180 ParTheta = parthe;
00181 }
00182
00183 void G4SPSPosDistribution::SetParPhi(G4double parphi)
00184 {
00185 ParPhi = parphi;
00186 }
00187
00188 void G4SPSPosDistribution::GenerateRotationMatrices()
00189 {
00190
00191
00192
00193
00194 Rotx = Rotx.unit();
00195 Roty = Roty.unit();
00196 Rotz = Rotx.cross(Roty);
00197 Rotz = Rotz.unit();
00198 Roty = Rotz.cross(Rotx);
00199 Roty = Roty.unit();
00200 if(verbosityLevel == 2)
00201 {
00202 G4cout << "The new axes, x', y', z' " << Rotx << " " << Roty << " " << Rotz << G4endl;
00203 }
00204 }
00205
00206 void G4SPSPosDistribution::ConfineSourceToVolume(G4String Vname)
00207 {
00208 VolName = Vname;
00209 if(verbosityLevel == 2)
00210 G4cout << VolName << G4endl;
00211 G4VPhysicalVolume *tempPV = NULL;
00212 G4PhysicalVolumeStore *PVStore = 0;
00213 G4String theRequiredVolumeName = VolName;
00214 PVStore = G4PhysicalVolumeStore::GetInstance();
00215 G4int i = 0;
00216 G4bool found = false;
00217 if(verbosityLevel == 2)
00218 G4cout << PVStore->size() << G4endl;
00219 while (!found && i<G4int(PVStore->size())) {
00220 tempPV = (*PVStore)[i];
00221 found = tempPV->GetName() == theRequiredVolumeName;
00222 if(verbosityLevel == 2)
00223 G4cout << i << " " << " " << tempPV->GetName() << " " << theRequiredVolumeName << " " << found << G4endl;
00224 if (!found)
00225 {i++;}
00226 }
00227
00228 if(found == true)
00229 {
00230 if(verbosityLevel >= 1)
00231 G4cout << "Volume " << VolName << " exists" << G4endl;
00232 Confine = true;
00233 }
00234 else
00235 {
00236 G4cout << " **** Error: Volume does not exist **** " << G4endl;
00237 G4cout << " Ignoring confine condition" << G4endl;
00238 Confine = false;
00239 VolName = "NULL";
00240 }
00241
00242 }
00243
00244 void G4SPSPosDistribution::GeneratePointSource()
00245 {
00246
00247 if(SourcePosType == "Point")
00248 particle_position = CentreCoords;
00249 else
00250 if(verbosityLevel >= 1)
00251 G4cout << "Error SourcePosType is not set to Point" << G4endl;
00252 }
00253
00254 void G4SPSPosDistribution::GeneratePointsInBeam()
00255 {
00256 G4double x, y, z;
00257
00258 G4ThreeVector RandPos;
00259 G4double tempx, tempy, tempz;
00260 z = 0.;
00261
00262
00263 if(Shape == "Circle")
00264 {
00265 x = Radius + 100.;
00266 y = Radius + 100.;
00267 while(std::sqrt((x*x) + (y*y)) > Radius)
00268 {
00269 x = posRndm->GenRandX();
00270 y = posRndm->GenRandY();
00271
00272 x = (x*2.*Radius) - Radius;
00273 y = (y*2.*Radius) - Radius;
00274 }
00275 x += G4RandGauss::shoot(0.0,SX) ;
00276 y += G4RandGauss::shoot(0.0,SY) ;
00277 }
00278 else
00279 {
00280
00281 x = posRndm->GenRandX();
00282 y = posRndm->GenRandY();
00283 x = (x*2.*halfx) - halfx;
00284 y = (y*2.*halfy) - halfy;
00285 x += G4RandGauss::shoot(0.0,SX);
00286 y += G4RandGauss::shoot(0.0,SY);
00287 }
00288
00289
00290 if(verbosityLevel >= 2)
00291 {
00292 G4cout << "Raw position " << x << "," << y << "," << z << G4endl;
00293 }
00294 tempx = (x * Rotx.x()) + (y * Roty.x()) + (z * Rotz.x());
00295 tempy = (x * Rotx.y()) + (y * Roty.y()) + (z * Rotz.y());
00296 tempz = (x * Rotx.z()) + (y * Roty.z()) + (z * Rotz.z());
00297
00298 RandPos.setX(tempx);
00299 RandPos.setY(tempy);
00300 RandPos.setZ(tempz);
00301
00302
00303 particle_position = CentreCoords + RandPos;
00304 if(verbosityLevel >= 1)
00305 {
00306 if(verbosityLevel >= 2)
00307 {
00308 G4cout << "Rotated Position " << RandPos << G4endl;
00309 }
00310 G4cout << "Rotated and Translated position " << particle_position << G4endl;
00311 }
00312 }
00313
00314 void G4SPSPosDistribution::GeneratePointsInPlane()
00315 {
00316 G4double x, y, z;
00317 G4double expression;
00318 G4ThreeVector RandPos;
00319 G4double tempx, tempy, tempz;
00320 x = y = z = 0.;
00321
00322 if(SourcePosType != "Plane" && verbosityLevel >= 1)
00323 G4cout << "Error: SourcePosType is not Plane" << G4endl;
00324
00325
00326 if(Shape == "Circle")
00327 {
00328 x = Radius + 100.;
00329 y = Radius + 100.;
00330 while(std::sqrt((x*x) + (y*y)) > Radius)
00331 {
00332 x = posRndm->GenRandX();
00333 y = posRndm->GenRandY();
00334
00335 x = (x*2.*Radius) - Radius;
00336 y = (y*2.*Radius) - Radius;
00337 }
00338 }
00339 else if(Shape == "Annulus")
00340 {
00341 x = Radius + 100.;
00342 y = Radius + 100.;
00343 while(std::sqrt((x*x) + (y*y)) > Radius || std::sqrt((x*x) + (y*y)) < Radius0 )
00344 {
00345 x = posRndm->GenRandX();
00346 y = posRndm->GenRandY();
00347
00348 x = (x*2.*Radius) - Radius;
00349 y = (y*2.*Radius) - Radius;
00350 }
00351 }
00352 else if(Shape == "Ellipse")
00353 {
00354 expression = 20.;
00355 while(expression > 1.)
00356 {
00357 x = posRndm->GenRandX();
00358 y = posRndm->GenRandY();
00359
00360 x = (x*2.*halfx) - halfx;
00361 y = (y*2.*halfy) - halfy;
00362
00363 expression = ((x*x)/(halfx*halfx)) + ((y*y)/(halfy*halfy));
00364 }
00365 }
00366 else if(Shape == "Square")
00367 {
00368 x = posRndm->GenRandX();
00369 y = posRndm->GenRandY();
00370 x = (x*2.*halfx) - halfx;
00371 y = (y*2.*halfy) - halfy;
00372 }
00373 else if(Shape == "Rectangle")
00374 {
00375 x = posRndm->GenRandX();
00376 y = posRndm->GenRandY();
00377 x = (x*2.*halfx) - halfx;
00378 y = (y*2.*halfy) - halfy;
00379 }
00380 else
00381 G4cout << "Shape not one of the plane types" << G4endl;
00382
00383
00384
00385 if(verbosityLevel == 2)
00386 {
00387 G4cout << "Raw position " << x << "," << y << "," << z << G4endl;
00388 }
00389 tempx = (x * Rotx.x()) + (y * Roty.x()) + (z * Rotz.x());
00390 tempy = (x * Rotx.y()) + (y * Roty.y()) + (z * Rotz.y());
00391 tempz = (x * Rotx.z()) + (y * Roty.z()) + (z * Rotz.z());
00392
00393 RandPos.setX(tempx);
00394 RandPos.setY(tempy);
00395 RandPos.setZ(tempz);
00396
00397
00398 particle_position = CentreCoords + RandPos;
00399 if(verbosityLevel >= 1)
00400 {
00401 if(verbosityLevel == 2)
00402 {
00403 G4cout << "Rotated Position " << RandPos << G4endl;
00404 }
00405 G4cout << "Rotated and Translated position " << particle_position << G4endl;
00406 }
00407
00408
00409 SideRefVec1 = Rotx;
00410 SideRefVec2 = Roty;
00411 SideRefVec3 = Rotz;
00412
00413
00414 if((CentreCoords.x() > 0. && Rotz.x() < 0.)
00415 || (CentreCoords.x() < 0. && Rotz.x() > 0.)
00416 || (CentreCoords.y() > 0. && Rotz.y() < 0.)
00417 || (CentreCoords.y() < 0. && Rotz.y() > 0.)
00418 || (CentreCoords.z() > 0. && Rotz.z() < 0.)
00419 || (CentreCoords.z() < 0. && Rotz.z() > 0.))
00420 {
00421
00422 SideRefVec2 = -SideRefVec2;
00423 SideRefVec3 = -SideRefVec3;
00424 }
00425 if(verbosityLevel == 2)
00426 {
00427 G4cout << "Reference vectors for cosine-law " << SideRefVec1 << " " << SideRefVec2 << " " << SideRefVec3 << G4endl;
00428 }
00429 }
00430
00431 void G4SPSPosDistribution::GeneratePointsOnSurface()
00432 {
00433
00434 G4double theta, phi;
00435 G4double x, y, z;
00436 x = y = z = 0.;
00437 G4ThreeVector RandPos;
00438
00439
00440 if(SourcePosType != "Surface" && verbosityLevel >= 1)
00441 G4cout << "Error SourcePosType not Surface" << G4endl;
00442
00443 if(Shape == "Sphere")
00444 {
00445
00446 theta = posRndm->GenRandPosTheta();
00447 phi = posRndm->GenRandPosPhi();
00448 theta = std::acos(1. - 2.*theta);
00449 phi = phi * 2. * pi;
00450
00451
00452 x = Radius * std::sin(theta) * std::cos(phi);
00453 y = Radius * std::sin(theta) * std::sin(phi);
00454 z = Radius * std::cos(theta);
00455
00456 RandPos.setX(x);
00457 RandPos.setY(y);
00458 RandPos.setZ(z);
00459
00460
00461 G4ThreeVector zdash(x,y,z);
00462 zdash = zdash.unit();
00463 G4ThreeVector xdash = Rotz.cross(zdash);
00464 G4ThreeVector ydash = xdash.cross(zdash);
00465 SideRefVec1 = xdash.unit();
00466 SideRefVec2 = ydash.unit();
00467 SideRefVec3 = zdash.unit();
00468 }
00469 else if(Shape == "Ellipsoid")
00470 {
00471 G4double minphi, maxphi, middlephi;
00472 G4double answer, constant;
00473
00474 constant = pi/(halfx*halfx) + pi/(halfy*halfy) +
00475 twopi/(halfz*halfz);
00476
00477
00478 theta = posRndm->GenRandPosTheta();
00479 phi = posRndm->GenRandPosPhi();
00480
00481 theta = std::acos(1. - 2.*theta);
00482 minphi = 0.;
00483 maxphi = twopi;
00484 while(maxphi-minphi > 0.)
00485 {
00486 middlephi = (maxphi+minphi)/2.;
00487 answer = (1./(halfx*halfx))*(middlephi/2. + std::sin(2*middlephi)/4.)
00488 + (1./(halfy*halfy))*(middlephi/2. - std::sin(2*middlephi)/4.)
00489 + middlephi/(halfz*halfz);
00490 answer = answer/constant;
00491 if(answer > phi) maxphi = middlephi;
00492 if(answer < phi) minphi = middlephi;
00493 if(std::fabs(answer-phi) <= 0.00001)
00494 {
00495 minphi = maxphi +1;
00496 phi = middlephi;
00497 }
00498 }
00499
00500 x = std::sin(theta)*std::cos(phi);
00501 y = std::sin(theta)*std::sin(phi);
00502 z = std::cos(theta);
00503
00504 G4double lhs;
00505
00506 G4double numYinX = y/x;
00507 G4double numZinX = z/x;
00508 G4double tempxvar;
00509 tempxvar= 1./(halfx*halfx)+(numYinX*numYinX)/(halfy*halfy)
00510 + (numZinX*numZinX)/(halfz*halfz);
00511
00512 tempxvar = 1./tempxvar;
00513 G4double coordx = std::sqrt(tempxvar);
00514
00515
00516 G4double numXinY = x/y;
00517 G4double numZinY = z/y;
00518 G4double tempyvar;
00519 tempyvar=(numXinY*numXinY)/(halfx*halfx)+1./(halfy*halfy)
00520 +(numZinY*numZinY)/(halfz*halfz);
00521 tempyvar = 1./tempyvar;
00522 G4double coordy = std::sqrt(tempyvar);
00523
00524
00525 G4double numXinZ = x/z;
00526 G4double numYinZ = y/z;
00527 G4double tempzvar;
00528 tempzvar=(numXinZ*numXinZ)/(halfx*halfx)
00529 +(numYinZ*numYinZ)/(halfy*halfy)+1./(halfz*halfz);
00530 tempzvar = 1./tempzvar;
00531 G4double coordz = std::sqrt(tempzvar);
00532
00533 lhs = std::sqrt((coordx*coordx)/(halfx*halfx) +
00534 (coordy*coordy)/(halfy*halfy) +
00535 (coordz*coordz)/(halfz*halfz));
00536
00537 if(std::fabs(lhs-1.) > 0.001 && verbosityLevel >= 1)
00538 G4cout << "Error: theta, phi not really on ellipsoid" << G4endl;
00539
00540
00541 G4double TestRandVar = G4UniformRand();
00542 if(TestRandVar > 0.5)
00543 {
00544 coordx = -coordx;
00545 }
00546 TestRandVar = G4UniformRand();
00547 if(TestRandVar > 0.5)
00548 {
00549 coordy = -coordy;
00550 }
00551 TestRandVar = G4UniformRand();
00552 if(TestRandVar > 0.5)
00553 {
00554 coordz = -coordz;
00555 }
00556
00557 RandPos.setX(coordx);
00558 RandPos.setY(coordy);
00559 RandPos.setZ(coordz);
00560
00561
00562 G4ThreeVector zdash(coordx,coordy,coordz);
00563 zdash = zdash.unit();
00564 G4ThreeVector xdash = Rotz.cross(zdash);
00565 G4ThreeVector ydash = xdash.cross(zdash);
00566 SideRefVec1 = xdash.unit();
00567 SideRefVec2 = ydash.unit();
00568 SideRefVec3 = zdash.unit();
00569 }
00570 else if(Shape == "Cylinder")
00571 {
00572 G4double AreaTop, AreaBot, AreaLat;
00573 G4double AreaTotal, prob1, prob2, prob3;
00574 G4double testrand;
00575
00576
00577
00578
00579
00580 AreaTop = pi * Radius * Radius;
00581 AreaBot = AreaTop;
00582 AreaLat = 2. * pi * Radius * 2. * halfz;
00583 AreaTotal = AreaTop + AreaBot + AreaLat;
00584
00585 prob1 = AreaTop / AreaTotal;
00586 prob2 = AreaBot / AreaTotal;
00587 prob3 = 1.00 - prob1 - prob2;
00588 if(std::fabs(prob3 - (AreaLat/AreaTotal)) >= 0.001)
00589 {
00590 if(verbosityLevel >= 1)
00591 G4cout << AreaLat/AreaTotal << " " << prob3<<G4endl;
00592 G4cout << "Error in prob3" << G4endl;
00593 }
00594
00595
00596
00597 testrand = G4UniformRand();
00598 if(testrand <= prob1)
00599 {
00600
00601 z = halfz;
00602 x = Radius + 100.;
00603 y = Radius + 100.;
00604 while(((x*x)+(y*y)) > (Radius*Radius))
00605 {
00606 x = posRndm->GenRandX();
00607 y = posRndm->GenRandY();
00608
00609 x = x * 2. * Radius;
00610 y = y * 2. * Radius;
00611 x = x - Radius;
00612 y = y - Radius;
00613 }
00614
00615 SideRefVec1 = Rotx;
00616 SideRefVec2 = Roty;
00617 SideRefVec3 = Rotz;
00618 }
00619 else if((testrand > prob1) && (testrand <= (prob1 + prob2)))
00620 {
00621
00622 z = -halfz;
00623 x = Radius + 100.;
00624 y = Radius + 100.;
00625 while(((x*x)+(y*y)) > (Radius*Radius))
00626 {
00627 x = posRndm->GenRandX();
00628 y = posRndm->GenRandY();
00629
00630 x = x * 2. * Radius;
00631 y = y * 2. * Radius;
00632 x = x - Radius;
00633 y = y - Radius;
00634 }
00635
00636 SideRefVec1 = Rotx;
00637 SideRefVec2 = -Roty;
00638 SideRefVec3 = -Rotz;
00639 }
00640 else if(testrand > (prob1+prob2))
00641 {
00642 G4double rand;
00643
00644
00645 rand = posRndm->GenRandPosPhi();
00646 rand = rand * 2. * pi;
00647
00648 x = Radius * std::cos(rand);
00649 y = Radius * std::sin(rand);
00650
00651 z = posRndm->GenRandZ();
00652
00653 z = z * 2. * halfz;
00654 z = z - halfz;
00655
00656
00657 G4ThreeVector zdash(x,y,0.);
00658 zdash = zdash.unit();
00659 G4ThreeVector xdash = Rotz.cross(zdash);
00660 G4ThreeVector ydash = xdash.cross(zdash);
00661 SideRefVec1 = xdash.unit();
00662 SideRefVec2 = ydash.unit();
00663 SideRefVec3 = zdash.unit();
00664 }
00665 else
00666 G4cout << "Error: testrand " << testrand << G4endl;
00667
00668 RandPos.setX(x);
00669 RandPos.setY(y);
00670 RandPos.setZ(z);
00671
00672 }
00673 else if(Shape == "Para")
00674 {
00675 G4double testrand;
00676
00677
00678
00679
00680
00681 testrand = G4UniformRand();
00682 G4double AreaX = halfy * halfz * 4.;
00683 G4double AreaY = halfx * halfz * 4.;
00684 G4double AreaZ = halfx * halfy * 4.;
00685 G4double AreaTotal = 2*(AreaX + AreaY + AreaZ);
00686 G4double Probs[6];
00687 Probs[0] = AreaX/AreaTotal;
00688 Probs[1] = Probs[0] + AreaX/AreaTotal;
00689 Probs[2] = Probs[1] + AreaY/AreaTotal;
00690 Probs[3] = Probs[2] + AreaY/AreaTotal;
00691 Probs[4] = Probs[3] + AreaZ/AreaTotal;
00692 Probs[5] = Probs[4] + AreaZ/AreaTotal;
00693
00694 x = posRndm->GenRandX();
00695 y = posRndm->GenRandY();
00696 z = posRndm->GenRandZ();
00697
00698 x = x * halfx * 2.;
00699 x = x - halfx;
00700 y = y * halfy * 2.;
00701 y = y - halfy;
00702 z = z * halfz * 2.;
00703 z = z - halfz;
00704
00705 if(testrand < Probs[0])
00706 {
00707
00708 x = halfx + z*std::tan(ParTheta)*std::cos(ParPhi) + y*std::tan(ParAlpha);
00709 y = y + z*std::tan(ParTheta)*std::sin(ParPhi);
00710
00711
00712 G4ThreeVector xdash(halfz*std::tan(ParTheta)*std::cos(ParPhi),
00713 halfz*std::tan(ParTheta)*std::sin(ParPhi),
00714 halfz/std::cos(ParPhi));
00715 G4ThreeVector ydash(halfy*std::tan(ParAlpha), -halfy, 0.0);
00716 xdash = xdash.unit();
00717 ydash = ydash.unit();
00718 G4ThreeVector zdash = xdash.cross(ydash);
00719 SideRefVec1 = xdash.unit();
00720 SideRefVec2 = ydash.unit();
00721 SideRefVec3 = zdash.unit();
00722 }
00723 else if(testrand >= Probs[0] && testrand < Probs[1])
00724 {
00725
00726 x = -halfx + z*std::tan(ParTheta)*std::cos(ParPhi) + y*std::tan(ParAlpha);
00727 y = y + z*std::tan(ParTheta)*std::sin(ParPhi);
00728
00729
00730 G4ThreeVector xdash(halfz*std::tan(ParTheta)*std::cos(ParPhi),
00731 halfz*std::tan(ParTheta)*std::sin(ParPhi),
00732 halfz/std::cos(ParPhi));
00733 G4ThreeVector ydash(halfy*std::tan(ParAlpha), halfy, 0.0);
00734 xdash = xdash.unit();
00735 ydash = ydash.unit();
00736 G4ThreeVector zdash = xdash.cross(ydash);
00737 SideRefVec1 = xdash.unit();
00738 SideRefVec2 = ydash.unit();
00739 SideRefVec3 = zdash.unit();
00740 }
00741 else if(testrand >= Probs[1] && testrand < Probs[2])
00742 {
00743
00744 x = x + z*std::tan(ParTheta)*std::cos(ParPhi) + halfy*std::tan(ParAlpha);
00745 y = halfy + z*std::tan(ParTheta)*std::sin(ParPhi);
00746
00747
00748 G4ThreeVector ydash(halfz*std::tan(ParTheta)*std::cos(ParPhi),
00749 halfz*std::tan(ParTheta)*std::sin(ParPhi),
00750 halfz/std::cos(ParPhi));
00751 ydash = ydash.unit();
00752 G4ThreeVector xdash = Roty.cross(ydash);
00753 G4ThreeVector zdash = xdash.cross(ydash);
00754 SideRefVec1 = xdash.unit();
00755 SideRefVec2 = -ydash.unit();
00756 SideRefVec3 = -zdash.unit();
00757 }
00758 else if(testrand >= Probs[2] && testrand < Probs[3])
00759 {
00760
00761 x = x + z*std::tan(ParTheta)*std::cos(ParPhi) - halfy*std::tan(ParAlpha);
00762 y = -halfy + z*std::tan(ParTheta)*std::sin(ParPhi);
00763
00764
00765 G4ThreeVector ydash(halfz*std::tan(ParTheta)*std::cos(ParPhi),
00766 halfz*std::tan(ParTheta)*std::sin(ParPhi),
00767 halfz/std::cos(ParPhi));
00768 ydash = ydash.unit();
00769 G4ThreeVector xdash = Roty.cross(ydash);
00770 G4ThreeVector zdash = xdash.cross(ydash);
00771 SideRefVec1 = xdash.unit();
00772 SideRefVec2 = ydash.unit();
00773 SideRefVec3 = zdash.unit();
00774 }
00775 else if(testrand >= Probs[3] && testrand < Probs[4])
00776 {
00777
00778 z = halfz;
00779 y = y + halfz*std::sin(ParPhi)*std::tan(ParTheta);
00780 x = x + halfz*std::cos(ParPhi)*std::tan(ParTheta) + y*std::tan(ParAlpha);
00781
00782 SideRefVec1 = Rotx;
00783 SideRefVec2 = Roty;
00784 SideRefVec3 = Rotz;
00785 }
00786 else if(testrand >= Probs[4] && testrand < Probs[5])
00787 {
00788
00789 z = -halfz;
00790 y = y - halfz*std::sin(ParPhi)*std::tan(ParTheta);
00791 x = x - halfz*std::cos(ParPhi)*std::tan(ParTheta) + y*std::tan(ParAlpha);
00792
00793 SideRefVec1 = Rotx;
00794 SideRefVec2 = -Roty;
00795 SideRefVec3 = -Rotz;
00796 }
00797 else
00798 {
00799 G4cout << "Error: testrand out of range" << G4endl;
00800 if(verbosityLevel >= 1)
00801 G4cout << "testrand=" << testrand << " Probs[5]=" << Probs[5] <<G4endl;
00802 }
00803
00804 RandPos.setX(x);
00805 RandPos.setY(y);
00806 RandPos.setZ(z);
00807 }
00808
00809
00810
00811 if(verbosityLevel == 2)
00812 G4cout << "Raw position " << RandPos << G4endl;
00813
00814 x=(RandPos.x()*Rotx.x())+(RandPos.y()*Roty.x())+(RandPos.z()*Rotz.x());
00815 y=(RandPos.x()*Rotx.y())+(RandPos.y()*Roty.y())+(RandPos.z()*Rotz.y());
00816 z=(RandPos.x()*Rotx.z())+(RandPos.y()*Roty.z())+(RandPos.z()*Rotz.z());
00817
00818 RandPos.setX(x);
00819 RandPos.setY(y);
00820 RandPos.setZ(z);
00821
00822
00823 particle_position = CentreCoords + RandPos;
00824
00825 if(verbosityLevel >= 1)
00826 {
00827 if(verbosityLevel == 2)
00828 G4cout << "Rotated position " << RandPos << G4endl;
00829 G4cout << "Rotated and translated position " << particle_position << G4endl;
00830 }
00831 if(verbosityLevel == 2)
00832 {
00833 G4cout << "Reference vectors for cosine-law " << SideRefVec1 << " " << SideRefVec2 << " " << SideRefVec3 << G4endl;
00834 }
00835 }
00836
00837 void G4SPSPosDistribution::GeneratePointsInVolume()
00838 {
00839 G4ThreeVector RandPos;
00840 G4double tempx, tempy, tempz;
00841 G4double x, y, z;
00842 x = y = z = 0.;
00843 if(SourcePosType != "Volume" && verbosityLevel >= 1)
00844 G4cout << "Error SourcePosType not Volume" << G4endl;
00845
00846 if(Shape == "Sphere")
00847 {
00848 x = Radius*2.;
00849 y = Radius*2.;
00850 z = Radius*2.;
00851 while(((x*x)+(y*y)+(z*z)) > (Radius*Radius))
00852 {
00853 x = posRndm->GenRandX();
00854 y = posRndm->GenRandY();
00855 z = posRndm->GenRandZ();
00856
00857 x = (x*2.*Radius) - Radius;
00858 y = (y*2.*Radius) - Radius;
00859 z = (z*2.*Radius) - Radius;
00860 }
00861 }
00862 else if(Shape == "Ellipsoid")
00863 {
00864 G4double temp;
00865 temp = 100.;
00866 while(temp > 1.)
00867 {
00868 x = posRndm->GenRandX();
00869 y = posRndm->GenRandY();
00870 z = posRndm->GenRandZ();
00871
00872 x = (x*2.*halfx) - halfx;
00873 y = (y*2.*halfy) - halfy;
00874 z = (z*2.*halfz) - halfz;
00875
00876 temp = ((x*x)/(halfx*halfx)) + ((y*y)/(halfy*halfy))
00877 + ((z*z)/(halfz*halfz));
00878 }
00879 }
00880 else if(Shape == "Cylinder")
00881 {
00882 x = Radius*2.;
00883 y = Radius*2.;
00884 while(((x*x)+(y*y)) > (Radius*Radius))
00885 {
00886 x = posRndm->GenRandX();
00887 y = posRndm->GenRandY();
00888 z = posRndm->GenRandZ();
00889
00890 x = (x*2.*Radius) - Radius;
00891 y = (y*2.*Radius) - Radius;
00892 z = (z*2.*halfz) - halfz;
00893 }
00894 }
00895 else if(Shape == "Para")
00896 {
00897 x = posRndm->GenRandX();
00898 y = posRndm->GenRandY();
00899 z = posRndm->GenRandZ();
00900 x = (x*2.*halfx) - halfx;
00901 y = (y*2.*halfy) - halfy;
00902 z = (z*2.*halfz) - halfz;
00903 x = x + z*std::tan(ParTheta)*std::cos(ParPhi) + y*std::tan(ParAlpha);
00904 y = y + z*std::tan(ParTheta)*std::sin(ParPhi);
00905
00906 }
00907 else
00908 G4cout << "Error: Volume Shape Doesnt Exist" << G4endl;
00909
00910 RandPos.setX(x);
00911 RandPos.setY(y);
00912 RandPos.setZ(z);
00913
00914
00915
00916 tempx = (x * Rotx.x()) + (y * Roty.x()) + (z * Rotz.x());
00917 tempy = (x * Rotx.y()) + (y * Roty.y()) + (z * Rotz.y());
00918 tempz = (x * Rotx.z()) + (y * Roty.z()) + (z * Rotz.z());
00919
00920 RandPos.setX(tempx);
00921 RandPos.setY(tempy);
00922 RandPos.setZ(tempz);
00923
00924
00925 particle_position = CentreCoords + RandPos;
00926
00927 if(verbosityLevel == 2)
00928 {
00929 G4cout << "Raw position " << x << "," << y << "," << z << G4endl;
00930 G4cout << "Rotated position " << RandPos << G4endl;
00931 }
00932 if(verbosityLevel >= 1)
00933 G4cout << "Rotated and translated position " << particle_position << G4endl;
00934
00935
00936 G4ThreeVector zdash(tempx,tempy,tempz);
00937 zdash = zdash.unit();
00938 G4ThreeVector xdash = Rotz.cross(zdash);
00939 G4ThreeVector ydash = xdash.cross(zdash);
00940 SideRefVec1 = xdash.unit();
00941 SideRefVec2 = ydash.unit();
00942 SideRefVec3 = zdash.unit();
00943
00944 if(verbosityLevel == 2)
00945 {
00946 G4cout << "Reference vectors for cosine-law " << SideRefVec1 << " " << SideRefVec2 << " " << SideRefVec3 << G4endl;
00947 }
00948 }
00949
00950 G4bool G4SPSPosDistribution::IsSourceConfined()
00951 {
00952
00953 if(Confine == false)
00954 G4cout << "Error: Confine is false" << G4endl;
00955 G4ThreeVector null(0.,0.,0.);
00956 G4ThreeVector *ptr;
00957 ptr = &null;
00958
00959
00960
00961 G4VPhysicalVolume *theVolume;
00962 theVolume=gNavigator->LocateGlobalPointAndSetup(particle_position,ptr,true);
00963 G4String theVolName = theVolume->GetName();
00964 if(theVolName == VolName)
00965 {
00966 if(verbosityLevel >= 1)
00967 G4cout << "Particle is in volume " << VolName << G4endl;
00968 return(true);
00969 }
00970 else
00971 return(false);
00972 }
00973
00974 G4ThreeVector G4SPSPosDistribution::GenerateOne()
00975 {
00976
00977 G4bool srcconf = false;
00978 G4int LoopCount = 0;
00979 while(srcconf == false)
00980 {
00981 if(SourcePosType == "Point")
00982 GeneratePointSource();
00983 else if(SourcePosType == "Beam")
00984 GeneratePointsInBeam();
00985 else if(SourcePosType == "Plane")
00986 GeneratePointsInPlane();
00987 else if(SourcePosType == "Surface")
00988 GeneratePointsOnSurface();
00989 else if(SourcePosType == "Volume")
00990 GeneratePointsInVolume();
00991 else
00992 {
00993 G4cout << "Error: SourcePosType undefined" << G4endl;
00994 G4cout << "Generating point source" << G4endl;
00995 GeneratePointSource();
00996 }
00997 if(Confine == true)
00998 {
00999 srcconf = IsSourceConfined();
01000
01001
01002 }
01003 else if(Confine == false)
01004 srcconf = true;
01005 LoopCount++;
01006 if(LoopCount == 100000)
01007 {
01008 G4cout << "*************************************" << G4endl;
01009 G4cout << "LoopCount = 100000" << G4endl;
01010 G4cout << "Either the source distribution >> confinement" << G4endl;
01011 G4cout << "or any confining volume may not overlap with" << G4endl;
01012 G4cout << "the source distribution or any confining volumes" << G4endl;
01013 G4cout << "may not exist"<< G4endl;
01014 G4cout << "If you have set confine then this will be ignored" <<G4endl;
01015 G4cout << "for this event." << G4endl;
01016 G4cout << "*************************************" << G4endl;
01017 srcconf = true;
01018 }
01019 }
01020 return particle_position;
01021 }
01022
01023
01024
01025