#include "WCSimPrimaryGeneratorAction.hh" #include "WCSimDetectorConstruction.hh" #include "WCSimPrimaryGeneratorMessenger.hh" #include "G4Event.hh" #include "G4ParticleGun.hh" #include "G4GeneralParticleSource.hh" #include "G4ParticleTable.hh" #include "G4ParticleDefinition.hh" #include "G4ThreeVector.hh" #include "globals.hh" #include "Randomize.hh" #include #include #include #include "G4Navigator.hh" #include "G4TransportationManager.hh" #include "G4PhysicalConstants.hh" #include "G4SystemOfUnits.hh" using std::vector; using std::string; using std::fstream; vector tokenize( string separators, string input ); inline vector readInLine(fstream& inFile, int lineSize, char* inBuf) { // Read in line break it up into tokens inFile.getline(inBuf,lineSize); return tokenize(" $", inBuf); } inline float atof( const string& s ) {return std::atof( s.c_str() );} inline int atoi( const string& s ) {return std::atoi( s.c_str() );} WCSimPrimaryGeneratorAction::WCSimPrimaryGeneratorAction( WCSimDetectorConstruction* myDC) :myDetector(myDC), vectorFileName("") { //T. Akiri: Initialize GPS to allow for the laser use MyGPS = new G4GeneralParticleSource(); // Initialize to zero mode = 0; vtxvol = 0; vtx = G4ThreeVector(0.,0.,0.); nuEnergy = 0.; _counterRock=0; // counter for generated in Rock _counterCublic=0; // counter generated //---Set defaults. Do once at beginning of session. G4int n_particle = 1; particleGun = new G4ParticleGun(n_particle); particleGun->SetParticleEnergy(1.0*GeV); particleGun->SetParticleMomentumDirection(G4ThreeVector(0.,0.,1.0)); G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable(); G4String particleName; particleGun-> SetParticleDefinition(particleTable->FindParticle(particleName="mu+")); particleGun-> SetParticlePosition(G4ThreeVector(0.*m,0.*m,0.*m)); messenger = new WCSimPrimaryGeneratorMessenger(this); useMulineEvt = true; useGunEvt = false; useLaserEvt = false; useGPSEvt = false; } WCSimPrimaryGeneratorAction::~WCSimPrimaryGeneratorAction() { if (IsGeneratingVertexInRock()){ G4cout << "Fraction of Rock volume is : " << G4endl; G4cout << " Random number generated in Rock / in Cublic = " << _counterRock << "/" << _counterCublic << " = " << _counterRock/(G4double)_counterCublic << G4endl; } inputFile.close(); delete particleGun; delete MyGPS; //T. Akiri: Delete the GPS variable delete messenger; } void WCSimPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent) { // We will need a particle table G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable(); // Temporary kludge to turn on/off vector text format G4bool useNuanceTextFormat = true; // Do for every event if (useMulineEvt) { if ( !inputFile.is_open() ) { G4cout << "Set a vector file using the command /mygen/vecfile name" << G4endl; exit(-1); } // // Documentation describing the nuance text format can be found here: // http://neutrino.phy.duke.edu/nuance-format/ // // The format must be strictly adhered to for it to be processed correctly. // The lines and their meanings from begin through info are fixed, and then // a variable number of tracks may follow. // if (useNuanceTextFormat) { const int lineSize=100; char inBuf[lineSize]; vector token(1); token = readInLine(inputFile, lineSize, inBuf); if (token.size() == 0) { G4cout << "end of nuance vector file!" << G4endl; } else if (token[0] != "begin") { G4cout << "unexpected line begins with " << token[0] << G4endl; } else // normal parsing begins here { // Read the nuance line (ignore value now) token = readInLine(inputFile, lineSize, inBuf); mode = atoi(token[1]); // Read the Vertex line token = readInLine(inputFile, lineSize, inBuf); vtx = G4ThreeVector(atof(token[1])*cm, atof(token[2])*cm, atof(token[3])*cm); // true : Generate vertex in Rock , false : Generate vertex in WC tank SetGenerateVertexInRock(false); // Next we read the incoming neutrino and target // First, the neutrino line token=readInLine(inputFile, lineSize, inBuf); beampdg = atoi(token[1]); beamenergy = atof(token[2])*MeV; beamdir = G4ThreeVector(atof(token[3]), atof(token[4]), atof(token[5])); // Now read the target line token=readInLine(inputFile, lineSize, inBuf); targetpdg = atoi(token[1]); targetenergy = atof(token[2])*MeV; targetdir = G4ThreeVector(atof(token[3]), atof(token[4]), atof(token[5])); // Read the info line, basically a dummy token=readInLine(inputFile, lineSize, inBuf); G4cout << "Vector File Record Number " << token[2] << G4endl; vecRecNumber = atoi(token[2]); // Now read the outgoing particles // These we will simulate. while ( token=readInLine(inputFile, lineSize, inBuf), token[0] == "track" ) { // We are only interested in the particles // that leave the nucleus, tagged by "0" if ( token[6] == "0") { G4int pdgid = atoi(token[1]); G4double energy = atof(token[2])*MeV; G4ThreeVector dir = G4ThreeVector(atof(token[3]), atof(token[4]), atof(token[5])); particleGun-> SetParticleDefinition(particleTable-> FindParticle(pdgid)); G4double mass = particleGun->GetParticleDefinition()->GetPDGMass(); G4double ekin = energy - mass; particleGun->SetParticleEnergy(ekin); //G4cout << "Particle: " << pdgid << " KE: " << ekin << G4endl; particleGun->SetParticlePosition(vtx); particleGun->SetParticleMomentumDirection(dir); particleGun->GeneratePrimaryVertex(anEvent); } } } } else { // old muline format inputFile >> nuEnergy >> energy >> xPos >> yPos >> zPos >> xDir >> yDir >> zDir; G4double random_z = ((myDetector->GetWaterTubePosition()) - .5*(myDetector->GetWaterTubeLength()) + 1.*m + 15.0*m*G4UniformRand())/m; zPos = random_z; G4ThreeVector vtx = G4ThreeVector(xPos, yPos, random_z); G4ThreeVector dir = G4ThreeVector(xDir,yDir,zDir); particleGun->SetParticleEnergy(energy*MeV); particleGun->SetParticlePosition(vtx); particleGun->SetParticleMomentumDirection(dir); particleGun->GeneratePrimaryVertex(anEvent); } } else if (useGunEvt) { // manual gun operation particleGun->GeneratePrimaryVertex(anEvent); G4ThreeVector P =anEvent->GetPrimaryVertex()->GetPrimary()->GetMomentum(); G4ThreeVector vtx=anEvent->GetPrimaryVertex()->GetPosition(); G4double m =anEvent->GetPrimaryVertex()->GetPrimary()->GetMass(); G4int pdg =anEvent->GetPrimaryVertex()->GetPrimary()->GetPDGcode(); G4ThreeVector dir = P.unit(); G4double E = std::sqrt((P.dot(P))+(m*m)); // particleGun->SetParticleEnergy(E); // particleGun->SetParticlePosition(vtx); // particleGun->SetParticleMomentumDirection(dir); SetVtx(vtx); SetBeamEnergy(E); SetBeamDir(dir); SetBeamPDG(pdg); } else if (useLaserEvt) { //T. Akiri: Create the GPS LASER event MyGPS->GeneratePrimaryVertex(anEvent); G4ThreeVector P =anEvent->GetPrimaryVertex()->GetPrimary()->GetMomentum(); G4ThreeVector vtx =anEvent->GetPrimaryVertex()->GetPosition(); G4int pdg =anEvent->GetPrimaryVertex()->GetPrimary()->GetPDGcode(); G4ThreeVector dir = P.unit(); G4double E = std::sqrt((P.dot(P))); SetVtx(vtx); SetBeamEnergy(E); SetBeamDir(dir); SetBeamPDG(pdg); } else if (useGPSEvt) { MyGPS->GeneratePrimaryVertex(anEvent); G4ThreeVector P =anEvent->GetPrimaryVertex()->GetPrimary()->GetMomentum(); G4ThreeVector vtx =anEvent->GetPrimaryVertex()->GetPosition(); G4double m =anEvent->GetPrimaryVertex()->GetPrimary()->GetMass(); G4int pdg =anEvent->GetPrimaryVertex()->GetPrimary()->GetPDGcode(); G4ThreeVector dir = P.unit(); G4double E = std::sqrt((P.dot(P))+(m*m)); SetVtx(vtx); SetBeamEnergy(E); SetBeamDir(dir); SetBeamPDG(pdg); } } void WCSimPrimaryGeneratorAction::SaveOptionsToOutput(WCSimRootOptions * wcopt) { if(useMulineEvt) wcopt->SetVectorFileName(vectorFileName); else wcopt->SetVectorFileName(""); wcopt->SetGeneratorType(GetGeneratorTypeString()); } G4String WCSimPrimaryGeneratorAction::GetGeneratorTypeString() { if(useMulineEvt) return "muline"; else if(useGunEvt) return "gun"; else if(useGPSEvt) return "gps"; else if(useLaserEvt) return "laser"; return ""; } // Returns a vector with the tokens vector tokenize( string separators, string input ) { std::size_t startToken = 0, endToken; // Pointers to the token pos vector tokens; // Vector to keep the tokens if( separators.size() > 0 && input.size() > 0 ) { while( startToken < input.size() ) { // Find the start of token startToken = input.find_first_not_of( separators, startToken ); // If found... if( startToken != input.npos ) { // Find end of token endToken = input.find_first_of( separators, startToken ); if( endToken == input.npos ) // If there was no end of token, assign it to the end of string endToken = input.size(); // Extract token tokens.push_back( input.substr( startToken, endToken - startToken ) ); // Update startToken startToken = endToken; } } } return tokens; }