I am trying to collect hit statistics for a detector to build up multiple point spread functions.
I have a primary generator that will fire 1 gamma particle (generator.cc). My generator has a function that can generate a random location for that 1 primary (GenerateRandomPosition()).
I would like to make a “run”: fire multiple primary particles (say 100) with that same random position, make another run to fire another 100 primary particles at a new random position, and so on.
I’ve set up a macro file to run a loop where it will iterate over the number of runs “runCount”
The problem is when I run this, every one of those 100 primary particles gets a new random position, instead of all 100 particles starting from the same position. Can I set a random position fixed for the 100 particles, per run, and loop over the runs, where each run gets a new random position?
loop.mac
/control/loop runPSF.mac runCount 1 10 1
runPSF.mac
/run/beamOn 100
generator.cc
MyPrimaryGenerator::MyPrimaryGenerator()
{
fParticleGun = new G4ParticleGun(1);
…
If you do not require the 100 particles to differ in another way (i.e. direction, momentum, polarization), you could simply do G4ParticleGun(100).
However, if that is not the case my approach would be to make have some way where the position id dependent on the ID of that run. I do not quite know how one would do that.
Maybe by using a G4UserRunAction::BeginOfRunAction() which changes the source somehow?
Or you could create a special RandomEngine that is seeded with the RunID, which GenerateRandomPosition() is using to get a random coordinate…?
I am quite a novice when it comes to Geant, so your mileage may vary, but this would be the direction I would investigate first.
The first thing that comes to mind is to generate the random position somewhere that is only run once for each call of BeamOn. I believe run action is called once for a run, and event action is called for each generated particle.
Yes, you’re right that this G4ParticleGun(100) approach does work. However, the tradeoff is that this only runs on a single thread, versus when you supply beamOn it can work on multiple threads. For my real sim I’m running quite a lot more primaries, so multithreading is a must.
I will try out the idea your other ideas with the RunAction and RunID based seed.