Hello, in G4.9.3 (and before), the function G4PrimaryTransformer::GimmePrimaries use the following loop: for( G4int i=0; i<n_vertex; i++ ) { GenerateTracks( anEvent->GetPrimaryVertex(i) ); } with inline G4PrimaryVertex* GetPrimaryVertex(G4int i=0) const { if( i == 0 ) { return thePrimaryVertex; } else if( i > 0 && i < numberOfPrimaryVertex ) { G4PrimaryVertex* primaryVertex = thePrimaryVertex; for( G4int j=0; j<i; j++ ) { if( primaryVertex == 0 ) return 0; primaryVertex = primaryVertex->GetNext(); } return primaryVertex; } else { return 0; } } So the loop inside GetPrimaryVertex goes through every vertex each time it is called, up to the requested one. It is not that bad with a low mulitplicity, but when it gets high, the time grows too fast. I propose the following modification, in order to not have to use two loops : G4TrackVector* G4PrimaryTransformer::GimmePrimaries(G4Event* anEvent,G4int trackIDCounter) { trackID = trackIDCounter; //TV.clearAndDestroy(); for( size_t ii=0; ii<TV.size();ii++) { delete TV[ii]; } TV.clear(); G4int n_vertex = anEvent->GetNumberOfPrimaryVertex(); if(n_vertex==0) return 0; G4PrimaryVertex *previousVertex=0, *newVertex=0; for( G4int i=0; i<n_vertex; i++ ) { newVertex= anEvent->GetPrimaryVertex(i, previousVertex); GenerateTracks( newVertex ); previousVertex = newVertex; } return &TV; } and inline G4PrimaryVertex* GetPrimaryVertex(G4int i=0, G4PrimaryVertex* lastVertex=0) const { if( i == 0) { return thePrimaryVertex; } else if( i > 0 && i < numberOfPrimaryVertex && lastVertex != 0) { return lastVertex->GetNext(); } else { return 0; } } I checked that it gives the same result (hopefully, I did not oversee anything). For a multiplicity of 100000 photons, it increased the speed of computation by a factor 15 ! Regards, Pierre
I noticed now that it may be useful to keep the possibility to have no "lastVertex" as an argument (at least for backward compatibility). So I would propose the following : inline G4PrimaryVertex* GetPrimaryVertex(G4int i=0, G4PrimaryVertex* lastVertex=0) const { if( i == 0) { return thePrimaryVertex; } else if( i > 0 && i < numberOfPrimaryVertex) { if (lastVertex != 0){ return lastVertex->GetNext(); } else { G4PrimaryVertex* primaryVertex = thePrimaryVertex; for( G4int j=0; j<i; j++ ) { if( primaryVertex == 0 ) return 0; primaryVertex = primaryVertex->GetNext(); } return primaryVertex; } } else { return 0; } }
Dear Pierre, Thanks for pointing this out. The implementation of G4PrimaryTransporfer will be changed as following, which I believe has the same effect as you proposed, without changes in other class. G4TrackVector* G4PrimaryTransformer::GimmePrimaries (G4Event* anEvent,G4int trackIDCounter) { trackID = trackIDCounter; //TV.clearAndDestroy(); for( size_t ii=0; ii<TV.size();ii++) { delete TV[ii]; } TV.clear(); G4PrimaryVertex* nextVertex = anEvent->GetPrimaryVertex(); while(nextVertex) { GenerateTracks(nextVertex); nextVertex = nextVertex->GetNext(); } return &TV; } This fix will show up in the next release. Kind regards, Makoto