// GLG4PrimaryGeneratorAction.cc // Contact person: Phil Jones // See GLG4PrimaryGeneratorAction.hh for more details //———————————————————————// #include #include #include "globals.hh" #include "G4Event.hh" #include "G4PrimaryVertex.hh" #include "G4Track.hh" #include "G4ios.hh" #include #include "CLHEP/Units/SystemOfUnits.h" #include "Randomize.hh" #include #include #include // for vertex generator #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include #include // for sprintf #include #include using namespace CLHEP; GLG4PrimaryGeneratorAction* GLG4PrimaryGeneratorAction::fTheGLG4PrimaryGeneratorAction=0; GLG4PrimaryGeneratorAction:: GLG4PrimaryGeneratorAction() : fEventGenerateProfile( "Gsim", "Generation" ) { if (fTheGLG4PrimaryGeneratorAction == 0) { fTheGLG4PrimaryGeneratorAction= this; } else { G4Exception(__FILE__, "Multiple Primary Generator Action", FatalException, "Error, more than one GLG4PrimaryGeneratorAction instantiated.\n" "Sorry, but this is a no-no because GLG4SteppingAction relies on\n" "GLG4PrimaryGeneratorAction::GetTheGLG4PrimaryGeneratorAction().\n" "This is yucky, I know -- please rewrite GLG4SteppingAction AND\n" "all main() programs so that constructor accepts a pointer to\n" "the GLG4PrimaryGeneratorAction you really want them to use."); } // initialize messenger and time fields fMessenger = new GLG4PrimaryGeneratorMessenger(this); fLastAddedGen = NULL; fUniversalTime= 0.0; fUniversalTimeSincePriorEvent= 0.0; // initialize generator state fEventWindow= 0.0 * ns; // load up factories with known generators // Generic generators RAT::GlobalFactory::Register("combo", new RAT::Alloc); RAT::GlobalFactory::Register("mixedevent", new RAT::Alloc); // These generators are used by combo to make a "custom" generator // Rate generators RAT::GlobalFactory::Register("uniform", new RAT::Alloc); RAT::GlobalFactory::Register("poisson", new RAT::Alloc); // Vertex generators RAT::GlobalFactory::Register("gun", new RAT::Alloc); RAT::GlobalFactory::Register("gun2", new RAT::Alloc); RAT::GlobalFactory::Register("gunpmtgamma", new RAT::Alloc); RAT::GlobalFactory::Register("pbomb", new RAT::Alloc); RAT::GlobalFactory::Register("mixedevent", new RAT::Alloc); // RAT::GlobalFactory::Register("lsbp", // new RAT::Alloc); // Position generators RAT::GlobalFactory::Register("point", new RAT::Alloc); RAT::GlobalFactory::Register("line", new RAT::Alloc); RAT::GlobalFactory::Register("linerotate", new RAT::Alloc); RAT::GlobalFactory::Register("plane", new RAT::Alloc); RAT::GlobalFactory::Register("planerpower", new RAT::Alloc); RAT::GlobalFactory::Register("paint", new RAT::Alloc); RAT::GlobalFactory::Register("fill", new RAT::Alloc); RAT::GlobalFactory::Register("fillexp", new RAT::Alloc); RAT::GlobalFactory::Register("fillshell", new RAT::Alloc); RAT::GlobalFactory::Register("fillrpower", new RAT::Alloc); RAT::GlobalFactory::Register("multipoint", new RAT::Alloc); RAT::GlobalFactory::Register("posellie", new RAT::Alloc); RAT::GlobalFactory::Register("poslaserball", new RAT::Alloc); RAT::GlobalFactory::Register("posufo", new RAT::Alloc); fNeedReset = true; } GLG4PrimaryGeneratorAction::~GLG4PrimaryGeneratorAction() { RAT::warn << "GLG4PrimaryGeneratorAction::~GLG4PrimaryGeneratorAction: Deleting generators." << newline; // Call the destructor of the generators. while (!fGenList.empty()) { GLG4Gen *gen = fGenList.top(); fGenList.pop(); #ifdef RAT_GEN_DEBUG RAT::info << " -> Deleting " << gen->GetName() << newline; #endif delete gen; } fLastAddedGen = NULL; } void GLG4PrimaryGeneratorAction::SetEventWindow(double argEventWindow) { fEventWindow= argEventWindow; } void GLG4PrimaryGeneratorAction::AddGenerator(GLG4Gen *gen) { #ifdef RAT_GEN_DEBUG RAT::info << "GLG4PrimaryGeneratorAction::AddGenerator : Adding generator " << gen->GetName() << newline; #endif; fGenList.push(gen); fLastAddedGen = gen; fNeedReset = true; } // GeneratePrimaries (this is the interesting part!) void GLG4PrimaryGeneratorAction::GeneratePrimaries(G4Event* argEvent) { // Profile the event generation proper fEventGenerateProfile.Start(); // Add RAT specific information here (FIXME in some alternate universe where // this program continues to be developed) argEvent->SetUserInformation(new RAT::EventInfo); if (fNeedReset) { // Need to reset the times of all the generators now that we've started // running. GLG4GenList temp; while (!fGenList.empty()) { GLG4Gen *gen = fGenList.top(); fGenList.pop(); gen->ResetTime(); temp.push(gen); } fGenList = temp; // copy them all back fNeedReset = false; } // Find time increment until next event on queue // (priority queue will always have next event on top) if (fGenList.empty()) G4Exception(__FILE__, "No Active Generator", FatalException, "GLG4PrimaryGeneratorAction: No generators selected!"); double timeToNextEvent = fGenList.top()->NextTime(); fUniversalTimeSincePriorEvent = timeToNextEvent; fUniversalTime += timeToNextEvent; // Offset time of all queued generators, so top generator's NextTime() == 0 fGenList.SubtractTime(timeToNextEvent); // Add all events in event window, includes pileup and deferred tracks while (!fGenList.empty() && fGenList.top()->NextTime() <= fEventWindow) { GLG4Gen *nextGen = fGenList.top(); fGenList.pop(); double vertexTime = nextGen->NextTime(); nextGen->GenerateEvent(argEvent); if (nextGen->IsRepeatable()) { // Reset time relative to time to previous generator time // to get pileup correct nextGen->ResetTime(vertexTime); fGenList.push(nextGen); } else delete nextGen; } fEventGenerateProfile.Stop(); } void GLG4PrimaryGeneratorAction::BeginOfRun() { GLG4GenList temp; while (!fGenList.empty()) { GLG4Gen *gen = fGenList.top(); fGenList.pop(); #ifdef RAT_GEN_DEBUG RAT::detail << "GLG4PrimaryGeneratorAction::BeginOfRun : Initializing Run for " << gen->GetName() << newline; gen->BeginOfRun(); RAT::detail << "GLG4PrimaryGeneratorAction::BeginOfRun : Initializing done for " << gen->GetName() << newline; #else gen->BeginOfRun(); #endif temp.push(gen); } fGenList = temp; // copy them all back #ifdef RAT_GEN_DEBUG RAT::detail << "GLG4PrimaryGeneratorAction::BeginOfRun : Initializing completed for all generators." << newline; #endif } void GLG4PrimaryGeneratorAction::EndOfRun() { GLG4GenList temp; while (!fGenList.empty()) { GLG4Gen *gen = fGenList.top(); fGenList.pop(); gen->EndOfRun(); temp.push(gen); } fGenList = temp; // copy them all back } void GLG4PrimaryGeneratorAction:: DeferTrackToLaterEvent(const G4Track * track) { fGenList.push(new GLG4Gen_DeferTrack(track)); }