Force a Run to stop or kill

Hello Geanters,

my question is in principle quite simple, but I haven’t found an answer.

I implemented a simple class to read LUND format files (pure ASCII). Perhaps I am re-inventing the wheel, but I see it as an programming exercise.

Everything works fine, open, reads and closes when finished the run. But the caveat is that it works, if the number of events in the file is same or smaller than the number of events invoked. So, I want to implement a condition to stop the run if the reader finds an eof.

I tried to call the RunManager and AbortRun(), but, at least in serial mode (for me the best for debugging), it moves to the event (which it found the eof), stop.

I just tried to declare the readfile method as bool, and return false for eof, so more or less works, but not enough.
For instance, my file has 2 events, I run/beamOn 5 events, the code process 0 and 1, try to read the file, starts 2, practically empty, and stop the run.

I would like to know if there is a way to stop the run (and the event) as soon the code finds the eof condition.


Please fill out the following information to help in answering your question, and also see tips for posting code snippets. If you don’t provide this information it will take more time to help with your problem!

Geant4 Version: geant4-11-02
Operating System: Fedora Linux 40
Compiler/Version: gcc (GCC) 14.2.1 20240912
CMake Version: cmake version 3.30.5


In your PrimaryGeneratorAction, you can call G4RunManager::GetRunManager()->AbortRun(finishEvent);. If finishEvent is true, the currently populated event will run to completion and then the job will end. If it’s false, then G4 will stop the event loop immediately.

Thank you for your fast answer, but sadly that solution doesn’t work. For debugging purposes, I am running with the environment “serial”. As you can see in this mess of output, I am still developing the code, so there are A LOT of labels to follow what is happening.

I am reading a file with just two events, but to test the code I run/beamOn 5

When moving to event 2, it finds the condition of eof but somehow continues the process, even after get a G4RunManager::GetRunManager()->AbortRun(finishEvent);.

What is more curious, is if I run multithreading (although 1 thread), it processes many more ‘empty’ events

It would be complicated to share a snippet, and I dare to share the repository, knowing that it will be an abuse ask to check the code, but if somebody is willing to take a look, it would be great.

A disclaimer, the request is in order to have an user proof code, the rude solution would exit(0) and make the user set the correct number of events to read.

LADEventAction::EndOfEventAction **** 1
Filling NTuples
***EVentID (finished): 1
Filled Energy NTuples
Filling NTuples
***EVentID: 1
Filled Position NTuples
Filling GEM
***EVentID: 1
Filled GEM leaves
IN FACT THIS IS THE BEGGINING OF THE NEW EVENT GeneratePrimaries: 2
LUND Event : 2
Reading the file

-------- EEEE ------- G4Exception-START -------- EEEE -------
*** G4Exception : Code001
      issued by : LADLUNDReader::ReadFile()
End of File. Exceed number of run/beamOn events

*** Run Must Be Aborted ***
 **** Track information is not available at this moment
 **** Step information is not available at this moment

-------- EEEE -------- G4Exception-END --------- EEEE -------

RETURN FALSE
<LADGEMSD> Initialize
<LADGEMSD> Initialize
LADEventAction::BeginOfEventAction ---- START: 2
<LADGEMSD> EndOfEvent

-------->Hits Collection: in this event they are 0 hits in the tracker chambers: 
<LADGEMSD> EndOfEvent

-------->Hits Collection: in this event they are 0 hits in the tracker chambers: 
LADEventAction::EndOfEventAction **** 2
Filling NTuples
***EVentID (finished): 2
Filled Energy NTuples
Filling NTuples
***EVentID: 2
Filled Position NTuples
Filling GEM
***EVentID: 2
Filled GEM leaves
<LADRunAction::EndOfRunAction()>: begin
 NbOfEvents: 3
>>>>>>>>>>>>>LUND generator (closing file)<<<<<<<<<<<  
LADLUNDReader Closing file

----> Histograms and ntuples are saved

Going to HodoAnalysis
<HodoAnalysis::EndOfRunAction>: begin
EoR: 3
Time Stamp <END>: 2025-01-31 - 17-36-20
Time Stamp <END>: 2025-01-31 - 17-36-20
<LADVariables::~LADVariables>: Finished
<LADConstants::~LADConstants>: End Read
<LADActionInitialization:: ~LADActionInitialization> closing 
<LADRunAction::~LADRunAction()>: closing
LADSteppingAction::~LADSteppingAction()->finishing
LADEventAction::~LADEventAction()

Well, there’s a separate managing instance for each thread, so yeah, that’s going to happen for every thread.

I presume that you’ve already properly coded a mutex so that your text file reader reads in a whole event in a given thread before letting the other threads even have access to it, right?

In that case, yeah, you’re going to get “dummy” events on all the other threads, as they see the EOF state left behind by the thread that reads the last event. Then that same thread will have one last opportunity and will see the EOF itself.

It looks like your code fills a hits collection. In that case, you could have your EndOfEventAction test for zero hits and just skip doing the N-tuple filling. We have a very similar “readback source” in the CDMS simulation, and we have a “skipEmptyEvents” flag for this purpose (sometimes it’s nice to record even the empty events for normalization, sometimes not).