In our Geant4 application, we simulate the responce of a detector to the air shower particles at ground level (2650m). We use Corsika as our event generator. The showers simulated can have primary energies up to 100TeV. These showers can produce up to 1mil particles at our detector level. For us, one air shower is one event. We simulate all the shower particles in one event using a loop in our UserPrimaryGeneratorAction. For every injected particle, Geant4 creates a G4PrimaryVertex and adds it in a list of primary vertexes. There is a loop in particles/management/include/G4PrimaryVertex.hh (inline function SetNext) that adds the new vertex at the end of the vertex list. In that function, for every event there is a loop starting from vertex #1 down to the last vertex. When the loop finds the last vertex it adds the new vertex to the list. This technique would be ok only for low number of primary particles per event. However, after some thousands of particles this loop takes alot of time. At 1mil particles the thing practically spends all of its time looping over the list of primary vertices. I'm sure there is a better way to do that and avoid all this delay. Like saving the number of events in the vertex list? For some people this would seem as a "feature" and not as a "bug", but for us it is a bug. It imposes an unnecessary artificial limitation on the number of primaries per event that Geant4 can simulate. I hope you'll give the problem the necessary attention. Thanks, Vlasios Vasileiou
The "default" design assumes a small number of verticies (with potentialy huge number of primaries sharing the same vertices). For your case, I presume each vertex has just a couple of particles but you have millions of vertices. If it is the case, you can use an alternative method of G4EventManager::ProcessOneEvent() which takes G4TrackVector, i.e. a vector of G4Track pointers of primary tracks. You have to do: 1) Create your own RunManager deriving from G4RunManager or just utilizing G4RunManagerKernel, so that you do not have to have PrimaryGeneratorAction. 2) In your RunManager, create a G4TrackVector and fill primary G4Track objects taken from Corsika. Then you are free from G4PrimaryVertex class.
Thanks for your prompt reply, First, a detail about our simulation: We have hundreds of thousands of different primary particles each own having its own vertex. My understanding is that one of the aims of the Geant4 collaboration is to provide a simulation toolkit that is generic enough to accomodate most of the reasonable user requirements. In this case, I don't think that being able to efficiently simulate events with multiple different primaries is an unreasonable requirement. Furthermore, the average user shouldn't spend his/her time and effort writing code to bypass the main Geant4 routines, espessially when a concrete example on how to do that is not available. (Should I submit a new user requirement?) I think it would be easier for me to try to patch the main Geant4 code than to use the method you proposed. After all, it seems like an easy thing to fix. Again, thanks for your time and help Vlasios Vasileiou