FindParticle("geantino");
}
G4double mass= fPDef->GetPDGMass();
G4PrimaryParticle* particle;
G4ThreeVector dir;
if (fMom.mag2() > 0.0) {
// fixed momentum and direction
particle= new G4PrimaryParticle(fPDef, // particle code
fMom.x(), // x component of momentum
fMom.y(), // y component of momentum
fMom.z()); // z component of momentum
dir= fMom.unit();
}
else {
// isotropic direction
/* generate random ThreeVector of unit length isotropically distributed on sphere by cutting two circles from a rectangular area and mapping circles onto top and bottom of sphere. N.B. the square of the radius is a uniform random variable. -GAHS.
*/
while (1) {
double u,v,q2;
// try first circle
u= 3.5*G4UniformRand()-1.75;
v= 2.0*G4UniformRand()-1.0;
q2= u*u + v*v;
if (q2 < 1.0) {
double rho_over_q= sqrt(2.0-q2);
dir= G4ThreeVector( u*rho_over_q,
v*rho_over_q,
1.0-q2 );
break;
}
// try second circle
u= (u>0.0) ? u-1.75 : u+1.75;
v= (v>0.0) ? v-1.00 : v+1.00;
q2= u*u + v*v;
if (q2 < 1.0) {
double rho_over_q= sqrt(2.0-q2);
dir= G4ThreeVector( u*rho_over_q,
v*rho_over_q,
q2-1.0 );
break;
}
}
G4ThreeVector rmom( dir * sqrt(fKe*(fKe+2.*mass)) );
particle= new G4PrimaryParticle(fPDef, // particle code
rmom.x(), // x component of momentum
rmom.y(), // y component of momentum
rmom.z() ); // z component of momentum
}
// adjust polarization if needed
if (fPDef->GetPDGSpin() == 1.0 && mass == 0.0) {
// spin 1 mass 0 particles should have transverse polarization
G4ThreeVector rpol= fPol - dir * (dir*fPol);
G4double rpolmag= rpol.mag();
if (rpolmag > 0.0) {
// use projected orthogonal pol, normalized
rpol *= (1.0/rpolmag);
}
else {
// choose random pol
G4double phi= (G4UniformRand()*2.0-1.0)*pi;
G4ThreeVector e1= dir.orthogonal().unit();
G4ThreeVector e2= dir.cross(e1);
rpol= e1*cos(phi)+e2*sin(phi);
}
particle->SetPolarization(rpol.x(), rpol.y(), rpol.z());
}
else {
// use user-set polarization unmodified
particle->SetPolarization(fPol.x(), fPol.y(), fPol.z());
}
particle->SetMass(mass); // Geant4 is silly.
vertex->SetPrimary( particle );
argEvent->AddPrimaryVertex(vertex);
}
}
/** Set state of the GLG4VertexGen_Gun, or show current state and
explanation of state syntax if empty string provided.
Format of argument to GLG4VertexGen_Gun::SetState:
"pname momx_MeV momy_MeV momz_MeV KE_MeV polx poly polz mult rand",
where
- pname is the name of a particle type (e-, mu-, U238, ...)
- mom*_MeV is a momentum in MeV/c
- KE_MeV is an optional override for kinetic energy
- pol* is an optional polarization vector.
If mom*_MeV==0 and KE_MeV!=0, then random isotropic directions chosen.
If pol*==0, then random transverse polarization for photons.
- mult is an optional multiplicity of the particles.
- rand is the possibility to vary the number of particles from event to event
that: fMultiplicity*G4UniformRand()+1;
*/
void GLG4VertexGen_Gun::
SetState(G4String newValues)
{
newValues = util_strip_default(newValues);
if (newValues.length() == 0) {
// print help and current state
G4cout << "Current state of this GLG4VertexGen_Gun:\n"
<< " \"" << GetState() << "\"\n" << G4endl;
G4cout << "Format of argument to GLG4VertexGen_Gun::SetState: \n"
" \"pname momx_MeV momy_MeV momz_MeV KE_MeV polx poly polz mult\"\n"
" where pname is the name of a particle type (e-, mu-, U238, ...)\n"
" mom*_MeV is a momentum in MeV/c\n"
" KE_MeV is an optional override for kinetic energy\n"
" pol* is an optional polarization vector.\n"
" mult is an optional multiplicity of the particles.\n"
" mom*_MeV==0 and KE_MeV!=0 --> random isotropic directions chosen\n"
" pol*==0 --> random transverse polarization for photons.\n"
<< G4endl;
return;
}
std::istringstream is(newValues.c_str());
// set particle
std::string pname;
is >> pname;
if (is.fail() || pname.length()==0)
return;
G4ParticleDefinition * newTestGunG4Code = G4ParticleTable::GetParticleTable()->FindParticle(pname);
if (newTestGunG4Code == NULL) {
// not a particle name
// see if we can parse it as an ion, e.g., U238 or Bi214
std::string elementName;
int A,Z;
if (pname[1] >= '0' && pname[1] <='9') {
A= atoi(pname.substr(1).c_str());
elementName= pname.substr(0,1);
}
else {
A= atoi(pname.substr(2).c_str());
elementName= pname.substr(0,2);
}
if (A > 0) {
for (Z=1; Z<=fNumberOfElements; Z++)
if (elementName == fTheElementNames[Z-1])
break;
if (Z <= fNumberOfElements)
newTestGunG4Code=G4IonTable::GetIonTable()->GetIon(Z, A, 0.0);
}
if (newTestGunG4Code == NULL) {
G4cerr << "test gun particle type not changed! Could not"
" find " << pname << G4endl;
return;
}
}
fPDef= newTestGunG4Code;
// set momentum
G4double x,y,z;
is >> x >> y >> z;
if (is.fail())
return;
fMom= G4ThreeVector(x*MeV,y*MeV,z*MeV);
fKe= sqrt(fMom.mag2()+fPDef->GetPDGMass()*fPDef->GetPDGMass())
- fPDef->GetPDGMass();
// optional override of kinetic energy
G4double p_renorm;
is >> x;
if (is.fail()) {
return;
}
if (x <= 0.0) {
p_renorm = 0.0;
fKe= 0.0;
}
else {
fKe= x*MeV;
if (fMom.mag2() <= 0.0)
p_renorm= 0.0;
else
p_renorm= sqrt( fKe*(fKe+2.0*newTestGunG4Code->GetPDGMass())
/ fMom.mag2() );
}
fMom *= p_renorm;
// set particle polarization
is >> x >> y >> z;
if (is.fail())
return;
fPol= G4ThreeVector(x,y,z);
// set multiplicity
is >> fMultiplicity;
// set if random
is >> fRandom;
if (is.fail()) { fRandom=0; return;}
}
G4String GLG4VertexGen_Gun::
GetState()
{
std::ostringstream os;
if (fPDef == 0) {
fPDef= G4ParticleTable::GetParticleTable()->FindParticle("geantino");
}
os << fPDef->GetParticleName() << '\t'
<< fMom.x() << ' ' << fMom.y() << ' ' << fMom.z() << '\t'
<< fKe << '\t'
<< fPol.x() << ' ' << fPol.y() << ' ' << fPol.z() << '\t'
<< fMultiplicity << ' '<< fRandom << std::ends;
G4String rv(os.str());
return rv;
}
////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////// Gun V2
const char * GLG4VertexGen_Gun2::fTheElementNames[] = {
"H", "He",
"Li", "Be", "B", "C", "N", "O", "F", "Ne",
"Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar",
"K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr",
"Rb", "Sr", "Y", "Zr", "Nb", "Mo","Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe",
"Cs", "Ba",
"La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu",
"Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn",
"Fr", "Ra",
"Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr",
"Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Xa"
};
GLG4VertexGen_Gun2::GLG4VertexGen_Gun2(const char *arg_dbname)
: GLG4VertexGen(arg_dbname), fMom(0.,0.,0.), fKe1(0.0), fKe2(0.0), fPol(0.,0.,0.),
fMultiplicity(1)
{
fPDef= G4ParticleTable::GetParticleTable()->FindParticle("geantino");
}
GLG4VertexGen_Gun2::~GLG4VertexGen_Gun2()
{
}
/** Generates one or more particles with a specified momentum, or isotropic
momentum with specific energy, and specified polarization, or uniformly
random polarization, based on parameters set via SetState() */
void GLG4VertexGen_Gun2::
GeneratePrimaryVertex(G4Event *argEvent, G4ThreeVector &dx, G4double dt)
{
G4PrimaryVertex* vertex= new G4PrimaryVertex( dx, dt );
if (fPDef == 0) {
fPDef= G4ParticleTable::GetParticleTable()->FindParticle("geantino");
}
G4double mass= fPDef->GetPDGMass();
G4PrimaryParticle* particle;
G4double _ke = (fKe2 - fKe1)*G4UniformRand()+fKe1;
G4ThreeVector dir;
if (fMom.mag2() > 0.0) {
if (fMomTheta > 0.0){ // emission into a cone of angle fMomTheta
G4double phi= twopi* G4UniformRand();
G4double cosTheta = 1.0 - (1.0 - cos(fMomTheta)) * G4UniformRand();
G4double sinTheta = sqrt(1. - cosTheta * cosTheta);
G4double ux = sinTheta * cos(phi);
G4double uy = sinTheta * sin(phi);
G4double uz = cosTheta;
dir = G4ThreeVector(ux,uy,uz);
dir.rotateY(fMom.theta());
dir.rotateZ(fMom.phi());
}
else
dir = fMom;
dir *= sqrt( _ke*(_ke+2*mass) / dir.mag2() );
particle= new G4PrimaryParticle(fPDef, // particle code
dir.x(), // x component of momentum
dir.y(), // y component of momentum
dir.z() ); // z component of momentum
dir = dir.unit();
}
else {
// isotropic direction
G4double phi= twopi* G4UniformRand();
G4double cosTheta = -1. + 2. * G4UniformRand();
G4double sinTheta = sqrt(1. - cosTheta * cosTheta);
G4double ux = sinTheta * cos(phi);
G4double uy = sinTheta * sin(phi);
G4double uz = cosTheta;
dir = G4ThreeVector(ux,uy,uz);
G4ThreeVector rmom( dir * sqrt(_ke*(_ke+2.*mass)) );
particle= new G4PrimaryParticle(fPDef, // particle code
rmom.x(), // x component of momentum
rmom.y(), // y component of momentum
rmom.z() ); // z component of momentum
}
// adjust polarization if needed
if (fPDef->GetPDGSpin() == 1.0 && mass == 0.0) {
// spin 1 mass 0 particles should have transverse polarization
G4ThreeVector rpol= fPol - dir * (dir*fPol);
G4double rpolmag= rpol.mag();
if (rpolmag > 0.0) {
// use projected orthogonal pol, normalized
rpol *= (1.0/rpolmag);
}
else {
// choose random pol
G4double phi= (G4UniformRand()*2.0-1.0)*pi;
G4ThreeVector e1= dir.orthogonal().unit();
G4ThreeVector e2= dir.cross(e1);
rpol= e1*cos(phi)+e2*sin(phi);
}
particle->SetPolarization(rpol.x(), rpol.y(), rpol.z());
}
else {
// use user-set polarization unmodified
particle->SetPolarization(fPol.x(), fPol.y(), fPol.z());
}
particle->SetMass(mass); // Geant4 is silly.
vertex->SetPrimary( particle );
argEvent->AddPrimaryVertex(vertex);
}
/** Set state of the GLG4VertexGen_Gun, or show current state and
explanation of state syntax if empty string provided.
Format of argument to GLG4VertexGen_Gun::SetState:
"pname momx_MeV momy_MeV momz_MeV KE_MeV polx poly polz mult",
where
- pname is the name of a particle type (e-, mu-, U238, ...)
- mom*_MeV is a momentum in MeV/c
- KE_MeV is an optional override for kinetic energy
- pol* is an optional polarization vector.
- mult is an optional multiplicity of the particles.
If mom*_MeV==0 and KE_MeV!=0, then random isotropic directions chosen.
If pol*==0, then random transverse polarization for photons.
*/
void GLG4VertexGen_Gun2::
SetState(G4String newValues)
{
newValues = util_strip_default(newValues);
if (newValues.length() == 0) {
// print help and current state
G4cout << "Current state of this GLG4VertexGen_Gun:\n"
<< " \"" << GetState() << "\"\n" << G4endl;
G4cout << "Format of argument to GLG4VertexGen_Gun::SetState: \n"
" \"pname momx_MeV momy_MeV momz_MeV KE1_MeV KE2_MeV \"\n"
" where pname is the name of a particle type (e-, mu-, U238, ...)\n"
" mom*_MeV is a momentum in MeV/c\n"
" KE1_MeV is the minimum kinetic energy\n"
" KE2_MeV is the maximum kinetic energy\n"
"mom*_MeV==0 --> random isotropic directions chosen\n"
<< G4endl;
return;
}
std::istringstream is(newValues.c_str());
// set particle
std::string pname;
is >> pname;
if (is.fail() || pname.length()==0)
return;
G4ParticleDefinition * newTestGunG4Code =
G4ParticleTable::GetParticleTable()->FindParticle(pname);
if (newTestGunG4Code == NULL) {
// not a particle name
// see if we can parse it as an ion, e.g., U238 or Bi214
std::string elementName;
int A,Z;
if (pname[1] >= '0' && pname[1] <='9') {
A= atoi(pname.substr(1).c_str());
elementName= pname.substr(0,1);
}
else {
A= atoi(pname.substr(2).c_str());
elementName= pname.substr(0,2);
}
if (A > 0) {
for (Z=1; Z<=fNumberOfElements; Z++)
if (elementName == fTheElementNames[Z-1])
break;
if (Z <= fNumberOfElements)
newTestGunG4Code= G4IonTable::GetIonTable()->GetIon(Z, A, 0.0);
}
if (newTestGunG4Code == NULL) {
G4cerr << "test gun particle type not changed! Could not"
" find " << pname << G4endl;
return;
}
}
fPDef= newTestGunG4Code;
// set momentum
G4double x,y,z;
is >> x >> y >> z;
if (is.fail())
return;
fMom= G4ThreeVector(x, y, z);
is >> x;
if (is.fail())
return;
fMomTheta = x * deg;
is >> x >> y;
if (is.fail())
return;
fKe1= x * MeV;
fKe2= y * MeV;
// set particle polarization
is >> x >> y >> z;
if (is.fail())
return;
fPol= G4ThreeVector(x,y,z);
// set multiplicity
is >> fMultiplicity;
// set if random
is >> fRandom;
if (is.fail())
return;
}
G4String GLG4VertexGen_Gun2::
GetState()
{
std::ostringstream os;
if (fPDef == 0) {
fPDef= G4ParticleTable::GetParticleTable()->FindParticle("geantino");
}
os << fPDef->GetParticleName() << '\t'
<< fMom.x() << ' ' << fMom.y() << ' ' << fMom.z() << '\t'
<< fKe1 << '\t'
<< fKe2 << '\t'
<< std::ends;
G4String rv(os.str());
return rv;
}
//////////////////////////////////////////////////////////////// end Gun2
GLG4VertexGen_HEPEvt::GLG4VertexGen_HEPEvt(const char *arg_dbname)
: GLG4VertexGen(arg_dbname)
{
fFileName="";
fFile= 0;
fIsPipe= false;
}
GLG4VertexGen_HEPEvt::~GLG4VertexGen_HEPEvt()
{
Close();
}
void GLG4VertexGen_HEPEvt::
Open(const char *argFilename)
{
if (argFilename == NULL || argFilename[0]=='\0') {
G4cerr << "GLG4VertexGen_HEPEvt::Open(): null filename" << G4endl;
return;
}
if (fFile != 0)
Close();
fFileName= argFilename;
// is a pipe requested?
if (argFilename[strlen(argFilename)-1]=='|') {
fIsPipe= true;
fFile= popen(fFileName.substr(0,fFileName.length()-1).c_str(), "r");
if (!fFile) {
perror(fFileName.c_str());
fFileName= "";
fIsPipe= false;
return;
}
}
else {
fIsPipe= false;
fFile= fopen(argFilename, "r");
if (!fFile) {
perror(fFileName.c_str());
fFileName= "";
return;
}
}
}
void GLG4VertexGen_HEPEvt::
Close()
{
if (fFile) {
if (fIsPipe) {
int status= pclose(fFile);
if (status != 0) {
G4cerr << "HEPEvt input pipe from " << fFileName
<< " gave status " << status << " on close." << G4endl;
}
fFile= 0;
fIsPipe= false;
fFileName= "";
}
else {
fclose(fFile);
fFile= 0;
fFileName= "";
}
}
}
void GLG4VertexGen_HEPEvt::
GetDataLine(char *buffer, size_t size)
{
int rewind_count= 0;
char firstword[64];
for (;;) {
buffer[0]= '\0';
if ( fgets(buffer, size, fFile) != buffer ) {
// try from beginning of file on failure
G4cerr << (feof(fFile) ? "End-of_file reached" : "Failure")
<< " on " << fFileName << " at " << ftell(fFile);
if (rewind_count == 0) {
if (fIsPipe == false) {
G4cerr << ", rewinding." << G4endl;
rewind(fFile);
}
else {
G4cerr << ", reopening." << G4endl;
pclose(fFile);
fFile= popen(fFileName.substr(0,fFileName.length()-1).c_str(), "r");
}
rewind_count++;
continue;
}
else {
G4cerr << ", closing." << G4endl;
Close();
return;
}
}
// check for "sentinel" block
firstword[0]= '\0';
sscanf(buffer, " %63s", firstword); // leading space means skip whitespace
if ( firstword[0]=='#' || firstword[0] == '\0' )
continue; // This is a comment line or blank line
if ( firstword[0] >= '0' && firstword[0] <= '9' )
break; // found numeric data -- first value is always non-neg int!
if ( strcmp(firstword, "STATE") == 0 ) {
double value;
int nscan;
while ( fgets(buffer, size, fFile) == buffer ) {
firstword[0]= '\0';
nscan= sscanf(buffer, " %63s %lf", firstword, &value);
if (firstword[0] == '#' || firstword[0] == '\0') continue;
if ( strcmp(firstword, "ENDSTATE") == 0 ) break;
if (nscan != 2)
{
G4cout << "Warning, bad STATE line in " << fFileName
<< ": " << buffer << G4endl;
}
}
continue;
}
else if ( strcmp(firstword, "HEPEVT")==0 ) {
char sentinel[20];
sentinel[0]= '\0';
sscanf(buffer, " HEPEVT DATA SENTINEL IS %19s", sentinel);
if (sentinel[0]== '\0') {
G4cerr << "Warning, line starting with word HEPEVT ignored" << G4endl;
continue;
}
// skip until sentinel found
while ( fgets(buffer, size, fFile) == buffer ) {
firstword[0]= '\0';
sscanf(buffer, " %63s", firstword);
if ( strcmp(firstword, sentinel)==0 )
break;
}
continue;
}
// not comment, blank line, STATE, or numeric data
G4cerr << "Warning, ignoring garbage line in " << fFileName << G4endl
<< buffer;
}
}
/** Generates one or more particles with type, momentum, and
optional time offset, spatial offset, and polarization,
based on lines read from file via SetState().
The file has the format
NHEP
ISTHEP IDHEP JDAHEP1 JDAHEP2 PHEP1 PHEP2 PHEP3 PHEP5 DT X Y Z PLX PLY PLZ
ISTHEP IDHEP JDAHEP1 JDAHEP2 PHEP1 PHEP2 PHEP3 PHEP5 DT X Y Z PLX PLY PLZ
ISTHEP IDHEP JDAHEP1 JDAHEP2 PHEP1 PHEP2 PHEP3 PHEP5 DT X Y Z PLX PLY PLZ
... [NHEP times]
NHEP
ISTHEP IDHEP JDAHEP1 JDAHEP2 PHEP1 PHEP2 PHEP3 PHEP5 DT X Y Z PLX PLY PLZ
ISTHEP IDHEP JDAHEP1 JDAHEP2 PHEP1 PHEP2 PHEP3 PHEP5 DT X Y Z PLX PLY PLZ
ISTHEP IDHEP JDAHEP1 JDAHEP2 PHEP1 PHEP2 PHEP3 PHEP5 DT X Y Z PLX PLY PLZ
... [NHEP times]
where
ISTHEP == status code
IDHEP == HEP PDG code
JDAHEP == first daughter
JDAHEP == last daughter
PHEP1 == px in GeV
PHEP2 == py in GeV
PHEP3 == pz in GeV
PHEP5 == mass in GeV
DT == vertex _delta_ time, in ns (*)
X == x vertex in mm
Y == y vertex in mm
Z == z vertex in mm
PLX == x polarization
PLY == y polarization
PLZ == z polarization
PHEP5, DT, X, Y, Z, PLX, PLY, and PLZ are all optional.
If omitted, the respective quantity is left unchanged.
If DT is specified, the time offset of this and subsequent vertices
is increased by DT: (*) note DT is a relative shift from the previous line!
(This is because there is often a very large dynamic range of time offsets
in certain types of events, e.g., in radioactive decay chains, and this
convention allows such events to be represented using a reasonable number
of significant digits.)
If X, Y, Z, PLX, PLY, and/or PLZ is specified, then the values replace
any previously specified.
*/
void GLG4VertexGen_HEPEvt::
GeneratePrimaryVertex(G4Event *argEvent, G4ThreeVector &dx, G4double dt)
{
// this is a modified and adapted version of G4HEPEvt
// (which itself may be a modified and adapted version of CLHEP/StdHep++...)
if (fFile == 0) {
G4cerr << "GLG4VertexGen_HEPEvt::GeneratePrimaryVertex: "
"Error, no file open!" << G4endl;
return;
}
char buffer[400];
int istat;
int NHEP; // number of entries
GetDataLine(buffer, sizeof(buffer));
if (fFile == 0) {
G4cerr << "Unexpected end of file in " << fFileName
<< ", expecting NHEP." << G4endl;
Close();
return;
}
istat= sscanf(buffer, "%d", &NHEP);
if ( istat != 1 ) {
// this should never happen: GetDataLine() should make sure integer is ok
// -- but the test above is cheap and a good cross-check, so leave it.
G4cerr << "Bad data in " << fFileName << ", expecting NHEP but got:\n"
<< buffer
<< " --> closing file." << G4endl;
Close();
return;
}
vector HPlist;
vector vertexList; // same indices as HPList
vector vertexSet; // bag of unique vertices
vertexSet.push_back( new G4PrimaryVertex(dx, dt) );
G4double vertexX=0.0, vertexY=0.0, vertexZ=0.0, vertexT=0.0;
for ( int IHEP=0; IHEP> ISTHEP >> IDHEP >> JDAHEP1 >> JDAHEP2
>> PHEP1 >> PHEP2 >> PHEP3 >> PHEP5
>> req_vertex_dT >> req_vertexX >> req_vertexY >> req_vertexZ // note order!
>> polx >> poly >> polz;
// reset units if "dimensionless" pseudo-particle information
if (ISTHEP >= kISTHEP_InformatonMin)
energy_unit= position_unit= time_unit= 1.0;
// frobnicate IDHEP if ISTHEP != 1
if (ISTHEP != kISTHEP_ParticleForTracking) {
if (ISTHEP <= 0 || ISTHEP > kISTHEP_Max) {
G4cerr << "Error in GLG4VertexGen_HEPEvt[" << fFileName
<< "]: ISTHEP=" << ISTHEP
<< " not allowed: valid range is 1 to 213"
<< " --> set to 213" << G4endl;
ISTHEP= kISTHEP_Max;
}
if (IDHEP < 0)
IDHEP -= kPDGcodeModulus*ISTHEP;
else
IDHEP += kPDGcodeModulus*ISTHEP;
}
// create G4PrimaryParticle object
// create an "ion" (nucleus) if IDHEP>9800000
G4PrimaryParticle* particle;
if (IDHEP > kIonCodeOffset && IDHEP < kIonCodeOffset+99999) {
int A= IDHEP%1000;
int Z= (IDHEP/1000)%100;
G4ParticleDefinition * g4code =
G4IonTable::GetIonTable()->GetIon(Z, A, 0.0);
if (g4code == 0) {
G4cerr << "Warning: GLG4HEPEvt could not find Ion Z=" << Z
<< " A=" << A << " code=" << IDHEP << G4endl;
particle = new G4PrimaryParticle(IDHEP,
PHEP1*energy_unit,
PHEP2*energy_unit,
PHEP3*energy_unit );
}
else {
particle = new G4PrimaryParticle(g4code,
PHEP1*energy_unit,
PHEP2*energy_unit,
PHEP3*energy_unit );
}
}
else if (IDHEP==0 && fabs(PHEP1)+fabs(PHEP2)+fabs(PHEP3)<20e-9) {
// special case: E less than ~10 eV and pdgcode=0 means optical photon
particle = new G4PrimaryParticle(G4OpticalPhoton::OpticalPhoton(),
PHEP1*energy_unit,
PHEP2*energy_unit,
PHEP3*energy_unit );
}
else {
particle = new G4PrimaryParticle(IDHEP,
PHEP1*energy_unit,
PHEP2*energy_unit,
PHEP3*energy_unit );
}
if (PHEP5 != req_novalue)
particle->SetMass( PHEP5*energy_unit );
if (polx != 0.0 || poly != 0.0 || polz != 0.0)
particle->SetPolarization(polx, poly, polz);
// create G4HEPEvtParticle object
G4HEPEvtParticle* hepParticle= new G4HEPEvtParticle(particle, ISTHEP, JDAHEP1, JDAHEP2);
// Store
HPlist.push_back( hepParticle );
// find or make the right vertex for this time and position
// as a special case, if a line doesn't have a value for position or time,
// then use the position and time previously set
if (req_vertexX==req_novalue && req_vertexY==req_novalue
&& req_vertexZ==req_novalue && req_vertex_dT==req_novalue) {
// no change, use current vertex
vertexList.push_back( vertexSet[vertexSet.size()-1] );
}
else {
// update vertex positions, and see if we can reuse an existing vertex
if (req_vertexX != req_novalue)
vertexX = req_vertexX * position_unit;
if (req_vertexY != req_novalue)
vertexY = req_vertexY * position_unit;
if (req_vertexZ != req_novalue)
vertexZ = req_vertexZ * position_unit;
if (req_vertex_dT != req_novalue)
vertexT = vertexT + req_vertex_dT * time_unit;// relative to prev line!
G4ThreeVector position(vertexX, vertexY, vertexZ);
int iv;
for (iv=vertexSet.size()-1; iv>=0; iv--) {
if ( vertexSet[iv]->GetT0() == vertexT
&& vertexSet[iv]->GetPosition() == position )
break; // found it
}
if (iv >= 0) // found?
vertexList.push_back(vertexSet[iv]);
else { // not found.
G4PrimaryVertex* nv= new G4PrimaryVertex(position, vertexT);
vertexSet.push_back(nv);
vertexList.push_back(nv);
}
}
}
// check if there is at least one particle
if(HPlist.empty()) return;
// make connection between daughter particles decayed from
// the same mother
for ( size_t i=0; iGetJDAHEP1() > 0 ){ // it has daughters
int jda1 = HPlist[i]->GetJDAHEP1()-1; // FORTRAN index starts from 1
int jda2 = HPlist[i]->GetJDAHEP2()-1; // but C++ starts from 0.
G4PrimaryParticle* mother = HPlist[i]->GetTheParticle();
for ( int j=jda1; j<=jda2; j++ ) {
G4PrimaryParticle* daughter = HPlist[j]->GetTheParticle();
if (HPlist[j]->GetISTHEP()>0) {
if ( vertexList[i]==vertexList[j] ) {
mother->SetDaughter( daughter );
HPlist[j]->Done();
}
else {
G4cerr << "Error in GLG4VertexGen_HEPEvt[" << fFileName
<< "]: mother " << i << " and daughter " << j
<< " are at different vertices, and this cannot be"
<< " done in Geant4! Must divorce mother and daughter."
<< G4endl;
}
}
}
}
}
// put initial particles to the vertex (or vertices)
for( size_t ii=0; iiGetISTHEP() > 0 ) // ISTHEP of daughters had been
// set to negative
{
G4PrimaryParticle* initialParticle = HPlist[ii]->GetTheParticle();
vertexList[ii]->SetPrimary( initialParticle );
}
}
// clear G4HEPEvtParticles
for(size_t iii=0;iiiAddPrimaryVertex( vertexSet[iv] );
}}
}
/** Set source of HEPEVT ascii data for this generator, or print
current source and help.
Format of string: either "filename" or "shell_command (arguments) |".
*/
void GLG4VertexGen_HEPEvt::
SetState(G4String newValues)
{
newValues = util_strip_default(newValues);
if (newValues.length() == 0) {
// print help and current state
G4cout << "Current state of this GLG4VertexGen_HEPEvt:\n"
<< " \"" << GetState() << "\"\n" << G4endl;
G4cout << "Format of argument to GLG4VertexGen_HEPEvt::SetState: \n"
<< "either \"filename\" or \"shell_command (arguments) |\"\n"
<< G4endl;
return;
}
Open(newValues);
}
G4String GLG4VertexGen_HEPEvt::
GetState()
{
return G4String(fFileName);
}
////////////////////////////////////////////////////////////////
#if 0
/* Below are the standard components for a "GLG4VertexGen": */
GLG4VertexGen_XXX::GLG4VertexGen_XXX(const char *arg_dbname)
: GLG4VertexGen(arg_dbname)
{
...
}
GLG4VertexGen_XXX::~GLG4VertexGen_XXX()
{
...
}
void GLG4VertexGen_XXX::
GeneratePrimaryVertex(G4Event *argEvent)
{
G4PrimaryVertex* vertex= new G4PrimaryVertex( 0.,0.,0.,0. );
pDef= G4ParticleTable::GetParticleTable()->FindParticle("geantino");
G4PrimaryParticle* particle;
particle=
new G4PrimaryParticle(pDef, // particle code
mom.x(), // x component of momentum
mom.y(), // y component of momentum
mom.z() ); // z component of momentum
particle->SetPolarization(rpol.x(), rpol.y(), rpol.z());
particle->SetMass(pDef->GetPDGMass()); // Geant4 is silly.
vertex->SetPrimary( particle );
argEvent->AddPrimaryVertex(vertex);
}
void GLG4VertexGen_XXX::
SetState(G4String newValues)
{
newValues = util_strip_default(newValues);
if (newValues.length() == 0) {
// print help and current state
G4cout << "Current state of this GLG4VertexGen_XXX:\n"
<< " \"" << GetState() << "\"\n" << G4endl;
G4cout << "Format of argument to GLG4VertexGen_XXX::SetState: \n"
<< G4endl;
return;
}
...
std::istringstream is(newValues.c_str());
}
G4String GLG4VertexGen_XXX::
GetState()
{
std::ostringstream os;
...
G4String rv(os.str());
return rv;
}
#endif