5 #include "G4ParticleGun.hh" 6 #include "G4ParticleTable.hh" 7 #include "G4ParticleDefinition.hh" 8 #include "Randomize.hh" 9 #include "G4UnitsTable.hh" 26 hd_msg = gemcOpt->
args[
"LOG_MSG"].args +
" Beam Settings >> " ;
27 input_gen = gemcOpt->args[
"INPUT_GEN_FILE"].args;
28 GEN_VERBOSITY = gemcOpt->args[
"GEN_VERBOSITY"].arg;
30 particleTable = G4ParticleTable::GetParticleTable();
34 particleGun =
new G4ParticleGun(1);
36 if(input_gen ==
"gemc_internal")
38 cout << endl << hd_msg <<
" Beam Type: " << Particle->GetParticleName() << endl;
39 cout << hd_msg <<
" Beam Momentum: " << G4BestUnit(mom,
"Energy") ;
40 if(dmom > 0) cout <<
" +- " << G4BestUnit(dmom,
"Energy") ;
42 cout << hd_msg <<
" Beam Direction: (theta, phi) = (" << theta/deg <<
", " << phi/deg <<
")" ;
43 if(dtheta > 0 || dphi > 0) cout <<
" +- (" << dtheta/deg <<
", " << dphi/deg <<
")" ;
44 cout <<
" deg " << endl;
45 cout << hd_msg <<
" Beam Vertex: (" << vx/cm <<
", " << vy/cm <<
", " << vz/cm <<
")" ;
46 if(dvr + dvz > 0) cout <<
" (radius, z-spread) = (" << dvr/cm <<
", " << dvz/cm <<
")" ;
47 cout <<
" cm " << endl;
48 cout << hd_msg <<
" Beam polarization: " << polDeg <<
"%" ;
50 cout << hd_msg <<
" Polarization Direction: (theta, phi) = (" << polTheta/deg <<
", " << polPhi/deg <<
")" ;
57 cout << endl << hd_msg <<
" Luminosity Particle Type: " << L_Particle->GetParticleName() << endl;
58 cout << hd_msg <<
" Luminosity Particle Momentum: " << G4BestUnit(L_Mom,
"Energy") ;
60 cout << hd_msg <<
" Luminosity Particle Direction: (theta, phi) = (" << L_Theta/deg <<
", " << L_Phi/deg <<
")" ;
61 cout <<
" deg " << endl;
62 cout << hd_msg <<
" Luminosity Particle Vertex: (" << L_vx/cm <<
", " << L_vy/cm <<
", " << L_vz/cm <<
")" ;
63 if(L_dvr + L_dvz > 0) cout <<
" (radius, z-spread) = (" << L_dvr/cm <<
", " << L_dvz/cm <<
")" ;
64 cout <<
" cm " << endl;
65 cout << hd_msg <<
" Number of Luminosity Particles: " << NP << endl;
66 cout << hd_msg <<
" Luminosity Time Window: " << TWINDOW/ns <<
" nanoseconds." << endl ;
67 cout << hd_msg <<
" Luminosity Time Between Bunches: " << TBUNCH/ns <<
" nanoseconds." << endl;
72 cout << endl << hd_msg <<
" Luminosity Particle 2 Type: " << L2_Particle->GetParticleName() << endl;
73 cout << hd_msg <<
" Luminosity Particle 2 Momentum: " << G4BestUnit(L2_Mom,
"Energy") ;
75 cout << hd_msg <<
" Luminosity Particle 2 Direction: (theta, phi) = (" << L2_Theta/deg <<
", " << L2_Phi/deg <<
")" ;
76 cout <<
" deg " << endl;
77 cout << hd_msg <<
" Luminosity Particle Vertex: (" << L2_vx/cm <<
", " << L2_vy/cm <<
", " << L2_vz/cm <<
")" ;
78 if(L2_dvr + L2_dvz > 0) cout <<
" (radius, z-spread) = (" << L2_dvr/cm <<
", " << L2_dvz/cm <<
")" ;
79 cout <<
" cm " << endl;
80 cout << hd_msg <<
" Number of Luminosity Particles 2: " << NP2 << endl;
81 cout << hd_msg <<
" Luminosity Time Between Bunches: " << TBUNCH2/ns <<
" nanoseconds." << endl;
90 if(input_gen ==
"gemc_internal")
93 if( gemcOpt->args[
"USE_QT"].arg > 0)
97 particleGun->SetParticleDefinition(Particle);
100 Mom = mom/MeV + (2.0*G4UniformRand()-1.0)*dmom/MeV;
101 Theta = theta/rad + (2.0*G4UniformRand()-1.0)*dtheta/rad;
102 Phi = phi/rad + (2.0*G4UniformRand()-1.0)*dphi/rad;
103 double mass = Particle->GetPDGMass();
104 double akine = sqrt(Mom*Mom + mass*mass) - mass ;
105 if(gemcOpt->args[
"ALIGN_ZAXIS"].args ==
"no")
106 beam_dir = G4ThreeVector(cos(Phi/rad)*sin(Theta/rad), sin(Phi/rad)*sin(Theta/rad), cos(Theta/rad));
107 else if(gemcOpt->args[
"ALIGN_ZAXIS"].args ==
"beamp")
109 beam_dir = G4ThreeVector(cos(phi/rad)*sin(theta/rad), sin(phi/rad)*sin(theta/rad), cos(theta/rad));
110 const G4ThreeVector beam_axis(cos(phi/rad)*sin(theta/rad), sin(phi/rad)*sin(theta/rad), cos(theta/rad));
111 const G4ThreeVector rotx1(cos(phi/rad), -sin(phi/rad), 0);
112 beam_dir.rotate((2.0*G4UniformRand()-1.0)*dtheta/rad, rotx1);
113 beam_dir.rotate((2.0*G4UniformRand()-1.0)*dphi/rad, beam_axis);
117 beam_dir = G4ThreeVector(cos(cphi/rad)*sin(ctheta/rad), sin(cphi/rad)*sin(ctheta/rad), cos(ctheta/rad));
119 const G4ThreeVector beam_axis(beam_dir);
120 const G4ThreeVector rotx1(cos(cphi/rad), -sin(cphi/rad), 0);
121 beam_dir.rotate(Theta, rotx1);
122 beam_dir.rotate(Phi, beam_axis);
125 particleGun->SetParticleEnergy(akine);
126 particleGun->SetParticleMomentumDirection(beam_dir);
129 double VR = sqrt(G4UniformRand())*dvr/mm;
130 double PHI = 2.0*
pi*G4UniformRand();
131 Vx = vx/mm + VR*cos(PHI);
132 Vy = vy/mm + VR*sin(PHI);
133 Vz = vz/mm + (2.0*G4UniformRand()-1.0)*dvz/mm;
134 beam_vrt = G4ThreeVector(Vx, Vy, Vz);
135 particleGun->SetParticlePosition(beam_vrt);
138 double partPol = 0.0;
139 double polCast = 100.0 * G4UniformRand();
140 if( polCast <= polDeg ) partPol = 1;
141 double polX = partPol * sin( polTheta/rad ) * cos( polPhi/rad );
142 double polY = partPol * sin( polTheta/rad ) * sin( polPhi/rad );
143 double polZ = partPol * cos( polTheta/rad );
144 beam_pol = G4ThreeVector( polX, polY, polZ );
145 particleGun->SetParticlePolarization(beam_pol);
148 particleGun->SetParticleTime(TWINDOW/2);
149 particleGun->GeneratePrimaryVertex(anEvent);
150 if(GEN_VERBOSITY > 3) {
151 cout << hd_msg <<
" Particle id=" << Particle->GetParticleName()
152 <<
" Vertex=" << beam_vrt <<
"cm, momentum=" << Mom/GeV <<
" GeV, theta=" 153 << Theta/deg <<
" degrees, phi=" << Phi/deg <<
" degrees" << endl;
154 if( partPol > 0 ) cout << hd_msg <<
" with polarization angles: polar - " << polTheta/deg <<
" degrees, " 155 "azimuthal - " << polPhi/deg <<
" degrees " ;
171 if(gformat ==
"LUND" && !gif.eof())
173 double tmp, px, py, pz;
174 int NPART, pdef, type, parent, daughter;
175 gif >> NPART >> tmp >> tmp >> targetPol >> beamPol >> tmp >> tmp >> tmp >> tmp >> tmp;
176 for(
int p=0; p<NPART; p++)
178 gif >> tmp >> tmp >> type >> pdef >> parent >> daughter >> px >> py >> pz >> tmp >> tmp >> Vx >> Vy >> Vz;
182 Particle = particleTable->FindParticle(pdef);
185 cout << hd_msg <<
" Particle id " << pdef <<
" not found in G4 table." << endl << endl;
189 particleGun->SetParticleDefinition(Particle);
192 G4ThreeVector pmom(px*GeV, py*GeV, pz*GeV);
195 Theta = pmom.getTheta();
196 double mass = Particle->GetPDGMass();
197 double akine = sqrt(Mom*Mom + mass*mass) - mass ;
199 beam_dir = G4ThreeVector(cos(Phi/rad)*sin(Theta/rad), sin(Phi/rad)*sin(Theta/rad), cos(Theta/rad));
200 particleGun->SetParticleEnergy(akine);
201 particleGun->SetParticleMomentumDirection(beam_dir);
204 beam_vrt = G4ThreeVector(Vx*cm, Vy*cm, Vz*cm);
205 particleGun->SetParticlePosition(beam_vrt);
212 beam_pol = G4ThreeVector( 0, 0, beamPol );
213 particleGun->SetParticlePolarization(beam_pol);
217 particleGun->SetParticleTime(TWINDOW/2);
218 particleGun->GeneratePrimaryVertex(anEvent);
219 if(GEN_VERBOSITY > 3)
220 cout << hd_msg <<
" Particle Number: " << p <<
", id=" << pdef <<
"(" << Particle->GetParticleName() <<
")" 221 <<
" Vertex=" << beam_vrt <<
"cm, momentum=" << pmom/GeV <<
" GeV" << endl;
230 int NBUNCHES = (int) floor(TWINDOW/TBUNCH);
231 int PBUNCH = (int) floor((
double)NP/NBUNCHES);
233 particleGun->SetParticleDefinition(L_Particle);
234 particleGun->SetParticlePosition(L_beam_vrt);
235 double L_mass = L_Particle->GetPDGMass();
236 double L_akine = sqrt(L_Mom*L_Mom + L_mass*L_mass) - L_mass ;
238 particleGun->SetParticleEnergy(L_akine);
239 particleGun->SetParticleMomentumDirection(L_beam_dir);
240 for(
int b=0; b<NBUNCHES; b++)
242 for(
int p=0; p<PBUNCH; p++)
245 double L_VR = G4UniformRand()*L_dvr/mm;
246 double L_PHI = 2.0*
pi*G4UniformRand();
247 L_vx = L_beam_vrt.x()/mm + L_VR*cos(L_PHI);
248 L_vy = L_beam_vrt.y()/mm + L_VR*sin(L_PHI);
249 L_vz = L_beam_vrt.z()/mm + (2.0*G4UniformRand()-1.0)*L_dvz/mm;
250 G4ThreeVector LUMI_V(L_vx, L_vy, L_vz);
251 particleGun->SetParticlePosition(LUMI_V);
252 particleGun-> SetParticleTime(TBUNCH*b);
253 particleGun->GeneratePrimaryVertex(anEvent);
259 int NBUNCHES2 = (int) floor(TWINDOW/TBUNCH2);
260 int PBUNCH2 = (int) floor((
double)NP2/NBUNCHES2);
262 particleGun->SetParticleDefinition(L2_Particle);
263 particleGun->SetParticlePosition(L2_beam_vrt);
264 double L2_mass = L2_Particle->GetPDGMass();
265 double L2_akine = sqrt(L2_Mom*L2_Mom + L2_mass*L2_mass) - L2_mass ;
268 particleGun->SetParticleEnergy(L2_akine);
269 particleGun->SetParticleMomentumDirection(L2_beam_dir);
270 for(
int b=0; b<NBUNCHES2; b++)
272 for(
int p=0; p<PBUNCH2; p++)
275 double L2_VR = G4UniformRand()*L2_dvr/mm;
276 double L2_PHI = 2.0*
pi*G4UniformRand();
277 L2_vx = L2_beam_vrt.x()/mm + L2_VR*cos(L2_PHI);
278 L2_vy = L2_beam_vrt.y()/mm + L2_VR*sin(L2_PHI);
279 L2_vz = L2_beam_vrt.z()/mm + (2.0*G4UniformRand()-1.0)*L2_dvz/mm;
280 G4ThreeVector LUMI2_V(L2_vx, L2_vy, L2_vz);
281 particleGun->SetParticlePosition(LUMI2_V);
283 particleGun-> SetParticleTime(TBUNCH2*b);
284 particleGun->GeneratePrimaryVertex(anEvent);
292 void MPrimaryGeneratorAction::setBeam()
294 string hd_msg = gemcOpt->args[
"LOG_MSG"].args +
" Beam Settings >> " ;
297 vector<string> values;
300 if(input_gen ==
"gemc_internal")
308 values =
get_info(gemcOpt->args[
"BEAM_P"].args);
317 Particle = particleTable->FindParticle(pname);
321 if(pname ==
"show_all")
323 for(
int i=0; i<particleTable->entries(); i++)
324 cout << hd_msg <<
" g4 particle: " << particleTable->GetParticleName(i)
325 <<
" pdg encoding: " << particleTable->GetParticle(i)->GetPDGEncoding() << endl;
329 cout << hd_msg <<
" Particle " << pname <<
" not found in G4 table. Exiting" << endl << endl;
335 values =
get_info(gemcOpt->args[
"ALIGN_ZAXIS"].args);
337 if(align ==
"custom")
344 values =
get_info(gemcOpt->args[
"SPREAD_P"].args);
350 values =
get_info(gemcOpt->args[
"BEAM_V"].args);
358 values =
get_info(gemcOpt->args[
"SPREAD_V"].args);
364 values =
get_info(gemcOpt->args[
"POLAR"].args);
373 gformat.assign( input_gen, 0, input_gen.find(
",")) ;
374 gfilename.assign(input_gen, input_gen.find(
",") + 1, input_gen.size()) ;
375 cout << hd_msg <<
" Opening " << gformat <<
" file: " <<
TrimSpaces(gfilename).c_str() << endl;
379 cerr << hd_msg <<
" Can't open input file " <<
TrimSpaces(gfilename).c_str() <<
". Exiting. " << endl;
390 values =
get_info(gemcOpt->args[
"LUMI_P"].args);
395 L_beam_dir = G4ThreeVector(cos(L_Phi/rad)*sin(L_Theta/rad), sin(L_Phi/rad)*sin(L_Theta/rad), cos(L_Theta/rad));
398 L_Particle = particleTable->FindParticle(L_pname);
402 if(L_pname ==
"show_all")
404 for(
int i=0; i<particleTable->entries(); i++)
405 cout << hd_msg <<
" g4 particle: " << particleTable->GetParticleName(i) << endl;
409 cout << hd_msg <<
" Particle " << L_pname <<
" not found in G4 table. Exiting" << endl << endl;
415 values =
get_info(gemcOpt->args[
"LUMI_V"].args);
420 L_beam_vrt = G4ThreeVector(L_vx, L_vy, L_vz);
423 values =
get_info(gemcOpt->args[
"LUMI_SPREAD_V"].args);
429 values =
get_info(gemcOpt->args[
"LUMI_EVENT"].args);
441 values =
get_info(gemcOpt->args[
"LUMI2_P"].args);
446 L2_beam_dir = G4ThreeVector(cos(L2_Phi/rad)*sin(L2_Theta/rad), sin(L2_Phi/rad)*sin(L2_Theta/rad), cos(L2_Theta/rad));
449 L2_Particle = particleTable->FindParticle(L2_pname);
453 if(L_pname ==
"show_all")
455 for(
int i=0; i<particleTable->entries(); i++)
456 cout << hd_msg <<
" g4 particle: " << particleTable->GetParticleName(i) << endl;
460 cout << hd_msg <<
" Particle " << L2_pname <<
" not found in G4 table. Exiting" << endl << endl;
466 values =
get_info(gemcOpt->args[
"LUMI2_V"].args);
471 L2_beam_vrt = G4ThreeVector(L2_vx, L2_vy, L2_vz);
475 values =
get_info(gemcOpt->args[
"LUMI2_SPREAD_V"].args);
481 values =
get_info(gemcOpt->args[
"LUMI2_EVENT"].args);
vector< string > get_info(string input)
get information from strings such as "5*GeV, 2*deg, 10*deg"
~MPrimaryGeneratorAction()
void GeneratePrimaries(G4Event *anEvent)
map< string, opts > args
Options map.
MPrimaryGeneratorAction(gemc_opts *)
string TrimSpaces(string in)
Removes leading and trailing spaces.
double get_number(string)
Returns dimension from string, i.e. 100*cm.