14 #include "G4ParticleGun.hh" 15 #include "G4ParticleTable.hh" 16 #include "G4ParticleDefinition.hh" 17 #include "G4ThreeVector.hh" 19 #include "Randomize.hh" 20 #include "G4UImanager.hh" 38 #include "Math/IFunction.h" 57 fProtonMomentumMag(120.0*
CLHEP::GeV),
68 fCorrectForAngle(true),
72 fBeamOffsetZ(-3.6*
CLHEP::
m),
76 fBeamMaxValX(1.0*
CLHEP::
m),
77 fBeamMaxValY(1.0*
CLHEP::
m),
78 fBeamSigmaX(1.3*
CLHEP::mm),
79 fBeamSigmaY(1.3*
CLHEP::mm),
82 fUseCourantSniderParams(true),
83 fUseJustSigmaCoord(false),
84 fRadiusAnnularBeam(-1.0),
85 fSigmaForAnnularbeam(-1.0),
88 fBeamBetaFunctionX(64.842),
89 fBeamBetaFunctionY(64.842),
90 fBeamBetaFunctionAt120(64.842),
91 fBeamBetaFunctionAt80(43.228),
92 fBeamBetaFunctionAt60(32.421),
95 fUseMuonGeantino(false),
96 fUseChargedGeantino(false),
97 fZOriginGeantino(-515.),
98 fSigmaZOriginGeantino(100.),
99 fPolarAngleGeantino(.005),
100 fPolarAngleGeantinoMin(0.),
101 fZOriginForMuGeantino(G4ThreeVector(0., 0., 0.)),
102 fYOriginForMuGeantino(G4ThreeVector(0., 0., 0.)),
103 fMomentumForMuGeantino(G4ThreeVector(7.5, 0., 0.)),
104 fAngleForMuGeantino(G4ThreeVector(0.01, 0., 0.))
108 G4int n_particle = 1;
138 G4Exception(
"LBNEPrimaryGeneratorAction::SetProtonBeam",
" ",
139 FatalErrorInArgument,
140 "Attempting to refdefined both CourantSnider parameters and beam spot size. Please choose one!..." );
142 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
145 fParticleGun->SetParticleDefinition(particleTable->FindParticle(
"geantino"));
148 fParticleGun->SetParticleDefinition(particleTable->FindParticle(
"mu+"));
151 fParticleGun->SetParticleDefinition(particleTable->FindParticle(
"chargedgeantino"));
153 else fParticleGun->SetParticleDefinition(particleTable->FindParticle(
"proton"));
156 const double pEkin = eBeam - 0.938272*CLHEP::GeV;
162 G4ThreeVector beamDirection(1,0,0);
165 G4cout <<
"Beam direction of " << beamDirection[0] <<
" " <<
166 beamDirection[1] <<
" " << beamDirection[2] <<
endl;
167 fParticleGun->SetParticleMomentumDirection(beamDirection);
177 G4String spaces =
" ";
178 std::cout << spaces <<
"Configuring the Proton beam..." <<
std::endl 179 << spaces <<
" Momentum = " <<
fParticleGun->GetParticleMomentum()/CLHEP::GeV <<
" GeV/c" <<
std::endl 180 << spaces <<
" Kinetic Energy = " <<
fParticleGun->GetParticleEnergy()/CLHEP::GeV <<
" GeV" <<
std::endl 192 const double gammaLorentz = eBeam/(0.938272*CLHEP::GeV);
193 const double betaLorentz = std::sqrt(1.0 - 1.0/(gammaLorentz*gammaLorentz));
194 const double betaGammaLorentz = gammaLorentz*betaLorentz;
211 std::cout << spaces <<
"Re-Configuring the Proton beam using Courant-Snider parameters " <<
std::endl;
213 std::cout << spaces <<
" Beta function Y at Point of creation " << fBeamBetaFuncGenY <<
" m " <<
std::endl;
216 std::cout << spaces <<
" Sigma X at Point of creation " << fBeamSigmaX <<
" mm " <<
std::endl;
226 int startSeed = CLHEP::HepRandom::getTheSeed();
228 gRandom =
new TRandom3(0);
229 gRandom->SetSeed(startSeed);
231 std::cout << spaces <<
" But.. but we will be using an annular beam, defined as follow " <<
std::endl;
232 std::cout << spaces <<
" f(r; R, sigma) = d^2N/drdTheta = " <<
std::endl;
233 std::cout << spaces <<
" = 1/(2*pi*sigma^2) * exp[(-r^2-R^2)/(2*sigma^2)] * I0(rR/sigma^2) " <<
std::endl;
236 std::cout << spaces <<
" This sigma is derived from Sigma X and Sigma Y, stated above " <<
std::endl;
242 const double stepR = 6.*fRadiusAnnularBeam/1000.;
243 for (
int kR=0.; kR != 1000; kR++) {
244 const double r = 0.49*stepR + kR*stepR;
245 const double f = (1.0/(2.0*M_PI*fSigSq)) * std::exp((-r*r -RSq)/(2.*fSigSq)) *
257 G4Exception(
"LBNEPrimaryGeneratorAction::OpenNtupleFLUKAASCII",
" ",
258 FatalErrorInArgument,
" Fluka Input file is not open, unexpected and fatal " );
264 G4Exception(
"LBNEPrimaryGeneratorAction::OpenNtupleFLUKAASCII",
" ",
265 FatalErrorInArgument,
" Fluka Input file no longer accessible " );
269 G4Exception(
"LBNEPrimaryGeneratorAction::GenerateFlukaPrimary",
" ",
270 FatalErrorInArgument,
" Fluka Input file is empty.... " );
281 G4String
message(
"Input Ntuple");
282 message += ntupleName + G4String(
"Not yet supported");
283 G4Exception(
"LBNEPrimaryGeneratorAction::OpenNtuple",
" ",
284 FatalErrorInArgument, message.c_str());
334 std::cout <<
" PROBLEM: Failed to close Input Ntuple " <<
fInputFile -> GetName() <<
std::endl;
342 std::cout <<
"LBNEPrimaryGeneratorAction::CloseNtuple() - " <<
std::endl;
343 std::cout <<
" Used " <<
fProtonN <<
" protons from input file" <<
endl;
355 G4Exception(
"LBNEPrimaryGeneratorAction::GetBetaFunctionvsBeamEnergy",
"", FatalException,
356 " With the current 1.2 MW option, the use of Courand Snider params and a beam energy != 120 GeV is prohibited ");
363 const double dp = pz - 80.;
364 std::cerr <<
" Using LBNEPrimaryGeneratorAction::GetBetaFunctionvsBeamEnergy... fBeamBetaFunctionAt120 " <<
372 int verboseLevel = G4EventManager::GetEventManager()->GetVerboseLevel();
375 std::cout <<
"Event " << anEvent->GetEventID() <<
": LBNEPrimaryGeneratorAction::GeneratePrimaries() Called." <<
std::endl;
383 G4cout<<
"Processing particles #: " 436 const double xFromEmitt = x0;
437 const double yFromEmitt = y0;
454 dz = std::sqrt(1.0 - (dx*dx + dy*dy));
465 phaseX = 2.0*M_PI*G4RandFlat::shoot();
466 const double amplX = xFromEmitt/std::cos(phaseX);
468 phaseY = 2.0*M_PI*G4RandFlat::shoot();
469 const double amplY = yFromEmitt/std::cos(phaseY);
471 dz = std::sqrt(1.0 - (dx*dx + dy*dy));
472 direction = G4ThreeVector(dx, dy, dz);
476 const double phi = 2.0*M_PI*G4RandFlat::shoot();
477 x0 = r*std::cos(phi);
478 y0 = r*std::sin(phi);
492 fParticleGun->SetParticlePosition(G4ThreeVector(x0,y0,z0));
520 const double dPhi = 2.0*M_PI*G4RandFlat::shoot();
524 double dx = dr*std::cos(dPhi);
526 double dy = dr*std::sin(dPhi);
527 double dz = sqrt(1.0 - (dx*dx + dy*dy));
538 double x = G4RandGauss::shoot(0.0, 1.3e-10);
539 double y = G4RandGauss::shoot(0.0, 1.3e-10);
554 if (doScanInZPos || doScanInYPos || doScanInMomentum || doScanInAngle) {
559 dz = std::sqrt(1.0 - dy*dy);
560 direction = G4ThreeVector(0., dy, dz);
572 const double pTotal = std::sqrt(pMu*pMu + Pt*Pt);
573 direction = G4ThreeVector(0., Pt/pTotal, pMu/pTotal);
574 fProtonMomentumMag = std::sqrt(pTotal*pTotal + (105.658*105.658*CLHEP::MeV*CLHEP::MeV));
580 fParticleGun->SetParticlePosition(G4ThreeVector(x, y, z));
619 G4Exception(
"LBNEPrimaryGeneratorAction::GenerateBeamFromInput",
" ",
620 FatalErrorInArgument,
" Input Ntuple not yet supported ");
630 G4double x0,y0,z0,px,py,pz;
631 G4String particleName;
636 x0 =
fInputTree->GetLeaf(
"x")->GetValue()*CLHEP::cm;
637 y0 =
fInputTree->GetLeaf(
"y")->GetValue()*CLHEP::cm;
642 px =
fInputTree->GetLeaf(
"px")->GetValue()*CLHEP::GeV;
643 py =
fInputTree->GetLeaf(
"py")->GetValue()*CLHEP::GeV;
644 pz =
fInputTree->GetLeaf(
"pz")->GetValue()*CLHEP::GeV;
654 fInputTree->GetLeaf(
"proty")->GetValue()*CLHEP::cm,
655 fInputTree->GetLeaf(
"protz")->GetValue()*CLHEP::cm);
657 fInputTree->GetLeaf(
"protpy")->GetValue()*CLHEP::cm,
658 fInputTree->GetLeaf(
"protpz")->GetValue()*CLHEP::cm);
672 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
673 fParticleGun->SetParticleDefinition(particleTable->FindParticle(particleName));
677 fParticleGun->SetParticlePosition(G4ThreeVector(x0,y0,z0));
678 fParticleGun->SetParticleMomentum(G4ThreeVector(px,py,pz));
687 G4Exception(
"LBNEPrimaryGeneratorAction::GenerateFlukaPrimary",
" ",
688 FatalErrorInArgument,
" Fluka Input file is not open, unexpected and fatal " );
692 G4Exception(
"LBNEPrimaryGeneratorAction::GenerateFlukaPrimary",
" ",
693 RunMustBeAborted,
" Fluka Input file no longer accessible " );
698 G4Exception(
"LBNEPrimaryGeneratorAction::GenerateFlukaPrimary",
" ",
699 RunMustBeAborted,
" Fluka Input file at EOF, no more events to generate " );
703 std::istringstream llStrStr(llStr);
704 G4ThreeVector beamPosition(0., 0., 0.);
705 for (
size_t k=0;
k !=3;
k++) { llStrStr >> beamPosition[
k]; beamPosition[
k] *= 1.0*CLHEP::cm; }
707 G4ThreeVector partMomentum(0.,0.,0.);
708 for (
size_t k=0;
k !=3;
k++) { llStrStr >> partMomentum[
k]; partMomentum[
k] *= 1.0*CLHEP::GeV; }
709 G4ThreeVector beamDirection(partMomentum);
710 double pTotTmp = beamDirection.mag();
711 for (
size_t k=0;
k !=3;
k++) beamDirection[
k] /= pTotTmp;
712 fParticleGun->SetParticleMomentumDirection(beamDirection);
714 llStrStr >> particleID;
715 G4ParticleTable *pTable=G4ParticleTable::GetParticleTable();
716 G4ParticleDefinition* pDef = pTable->FindParticle(particleID);
718 const double pMass = pDef->GetPDGMass();
719 const double eTot = std::sqrt(pMass*pMass + pTotTmp*pTotTmp);
G4double fBeamBetaFunctionY
G4bool OpenNtupleFLUKAASCII(G4String ntupleName)
G4ThreeVector fMomentumForMuGeantino
G4double fRadiusAnnularBeam
std::ifstream fFlukaASCII
G4bool fUseJustSigmaCoord
LBNEPrimaryGeneratorAction()
void GenerateBeamFromInput(G4Event *anEvent)
double GetBetaFunctionvsBeamEnergy(double pz)
LBNERunManager * fRunManager
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
~LBNEPrimaryGeneratorAction()
LBNEParticleCode_t IntToEnum(G4int particleInt)
G4double fZOriginGeantino
G4bool fUseCourantSniderParams
TF1 * theModBesselFunc1rstKind
G4int GetNumberOfEvents()
G4double fBeamBetaFunctionAt120
G4double fPolarAngleGeantinoMin
G4double fPolarAngleGeantino
G4bool OpenNtuple(G4String ntupleName)
G4double fBeamBetaFuncGenX
G4ThreeVector fParticlePosition
G4ThreeVector fParticleMomentum
G4double fProtonMomentumMag
void GeneratePrimaries(G4Event *anEvent)
G4double fSigmaForAnnularbeam
G4ParticleGun * fParticleGun
G4double fBeamAlphaFunctionY
void Geantino(G4Event *anEvent)
G4String AsString(LBNEParticleCode_t pCode)
G4ThreeVector fYOriginForMuGeantino
G4ThreeVector fPtForMuGeantino
G4double fBeamBetaFunctionX
G4double fBeamBetaFunctionAt80
G4bool fUseChargedGeantino
G4ThreeVector fZOriginForMuGeantino
G4ThreeVector fProtonIntVertex
LBNEPrimaryMessenger * fPrimaryMessenger
size_t maxLengthForFlukaLine
G4ThreeVector fProtonOrigin
G4double fBeamAlphaFunctionX
G4double fBeamBetaFunctionAt60
G4double fBeamBetaFuncGenY
void GenerateG4ProtonBeam(G4Event *anEvent)
G4double fSigmaZOriginGeantino
void GenerateFlukaPrimary(G4Event *anEvent)
QTextStream & endl(QTextStream &s)
G4ThreeVector fProtonMomentum
G4ThreeVector fAngleForMuGeantino