Multithreading leads to Detector not working Properly

Hello there,

until recently i was tracking Particles in my stepping action (which worked fine) but i wanted to move to a different approach using my detector like this and thus recording particles in a different way:

    SensitiveDetector::SensitiveDetector(G4String name): G4VSensitiveDetector(name) {}
    SensitiveDetector::~SensitiveDetector() {}
    void SensitiveDetector::Initialize(G4HCofThisEvent* hce) {G4cout << "Sensitive Detector 
    Initialized" << G4endl;}

    G4bool SensitiveDetector::ProcessHits(G4Step *aStep, G4TouchableHistory *ROhist) {
   	if (GetName() == "EnergyDetector") {
             //if (parentID != 1){
    
    G4double totalEnergy = aStep->GetTotalEnergyDeposit();
    Global::EDeposit += totalEnergy;

            //G4cout << "Hit registered on Energy Detector! Parent ID:" << parentID << G4endl;

    return true;
            //}
}

return false;
}

void SensitiveDetector::EndOfEvent(G4HCofThisEvent* hce) {}

This should add up the deposited energy in my detector throughout an event in a global Variable called EDeposit. At the beginning of the event this is set to zero and at the end of an event this is written in a Root-File. My Problem is that once i use multithreading the energy recorded at the end of an event doesnt match the one being recorded through the stepping action method. Comparing both methods at each step, instead of the end of an event, suggests that the recording of the energy is the same at each step, so the problem has to lie within me adding the energies up throughout the event (probably multiple threads trying to changing the variable at the same time). i tried using EDeposit as an atomic variable since i saw that being suggested somewhere but without any success. Introducing a mutex would defeat the purpose of multithreading since that would mean there can only be one event being processed at the time.
Do you have any suggestions on how to tackle this task?

Thank you very much in advance!
Best Regards,
Tim

Global variables are shared across all the threads, so you’re getting the sum of all the events being processed simulatenously across the threads. You can make yourself a thread-local singleton container to carry these kinds of quanitities, which you can then access from your various modules.

The Geant4 documentation has a lot of good, detailed discussion about how to do this, and they provide some convenient tools, such as the G4ThreadLocalSingleton templated friend class to handle the instantiations.

1 Like

Thank you so much for your help!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.