// 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));
}