Track optical photons as they are generated

I am running a G4 program using G4FastSimulation physics to integrate packages such as Garfield. Within this program I am writing my own simple photon generation function, see the code below. One issue I have is my simulation creates ~1e7 optical photons per event and the memory grows to 25 - 30 GB. I think in the usual Scintillation and Cherenkov modules there is a way that halts the primary and tracks the photons which I think can avoid this issue of significant memory usage. Is there a way I can set this in my program via the G4FastStep/G4FastTrack?

Short summary of how scintillation code works (I’ve tried to reduce it to make it clear). This function gets called for every ionisation electron in the event.


int N = GetPhotonYield(); // This function just returns the number of photons

for (int idx = 0; idx < N; idx++){
 auto* optphot = G4OpticalPhoton::OpticalPhotonDefinition();
 G4DynamicParticle VUVphoton(optphot,G4RandomDirection(), 7.2*eV);

 G4Track *newTrack=fastStep.CreateSecondaryTrack(VUVphoton, pos, time, false); // fastStep is a G4FastStep object

}

Thanks very much for your help!

I am using Geant4 version v11.1.1

1 Like

The way it is done in G4Cerenkov and G4Scintillation is to suspend the primary track.
https://geant4.kek.jp/lxr/source/processes/electromagnetic/xrays/src/G4Cerenkov.cc#L272

  if(fTrackSecondariesFirst)
  {
    if(aTrack.GetTrackStatus() == fAlive)
      aParticleChange.ProposeTrackStatus(fSuspend);
  }

Hi @dsawkey, thanks very much for the suggestion!

I had a go at implementing this and unfortunately the memory is still growing from adding the photons to the stack (if I comment out the call to CreateSecondaryTrack the memory stays below 2GB compared to 30GB with it turned on). I think it’s due to the weirdness of how the Garfield interface works with G4. In this application, I kill the primary ionisation electron from G4 and Garfield take over. It is then drifted to a photon multiplication region where I then make this function call to add secondaries. You can see the status of the primary electron in this fastStep.Dump()

G4WT0 >         G4VParticleChange Information 
G4WT0 >         TrackID             : 347369
G4WT0 >         ParentID            : 1731
G4WT0 >         Particle            : thermalelectron
G4WT0 >         Kinetic energy (MeV): 1.1894244e-12
G4WT0 >         Position (mm)       : (0.17610002,-16.007758,-50.072829)
G4WT0 >         Direction           : (0,0,1)
G4WT0 >         PhysicsVolume       : GAS
G4WT0 >         Material            : GXe
G4WT0 >       -----------------------------------------------
G4WT0 >         # of secondaries    :                  662
G4WT0 >       -----------------------------------------------
G4WT0 >         Energy Deposit (MeV):                    0
G4WT0 >    NIEL Energy Deposit (MeV):                    0
G4WT0 >         Track Status        :          StopAndKill
G4WT0 >         TruePathLength (mm) :                    0
G4WT0 >         Stepping Control    :                    1
G4WT0 >        First step in volume
G4WT0 >         Position - x (mm)   : 176.1 um 
G4WT0 >         Position - y (mm)   : -1.60078 cm 
G4WT0 >         Position - z (mm)   : -5.00728 cm 
G4WT0 >         Time (ns)           : 204.229 ps 
G4WT0 >         Proper Time (ns)    : 0 ps 
G4WT0 >         Momentum Direct - x :                    0
G4WT0 >         Momentum Direct - y :                    0
G4WT0 >         Momentum Direct - z :                    1
G4WT0 >         Kinetic Energy (MeV): 0 eV 
G4WT0 >         Polarization - x    :                    0
G4WT0 >         Polarization - y    :                    0
G4WT0 >         Polarization - z    :                    0
G4WT0 >       -----------------------------------------------

I have also tried to set the fSuspend status to the secondaries in this similar way using the following code (and have verified the status of the tracks are indeed with status fSuspend) but this did not seem to help.

// Loop over the secondary tracks and set their tracking status
G4int N_secondaries = fastStep.GetNumberOfSecondaries();
for (G4int i = 0; i < N_secondaries; i++){
  G4Track *secondary = fastStep.GetSecondaryTrack(i);
  secondary->SetTrackStatus(fSuspend);
}
1 Like

You don’t want to suspend the secondaries. What you want to do is to suspect the parent track itself. The idea is that the track takes a step, creates a small number of secondaries, then the track is suspended and the secondaries are immediately tracked to completion. The parent track will then resume, take another step, and create a small number of secondaries. Rinse and repeat.