Hello everyone,
I’m encountering a strange issue in multithreaded (MT) mode. Although thread-local files are being created, the data from EndOfEventAction (specifically m_analysisManager->AddNtupleRow(ntupleId)
) appears to be written to the master-thread file instead:
rw-r--r-- 1 geant4 geant4 990787 Dec 12 19:04 mcGeant.root
-rw-r--r-- 1 geant4 geant4 172 Dec 12 19:04 mcGeant_t0.root
-rw-r--r-- 1 geant4 geant4 172 Dec 12 19:04 mcGeant_t1.root
-rw-r--r-- 1 geant4 geant4 172 Dec 12 19:04 mcGeant_t2.root
-rw-r--r-- 1 geant4 geant4 172 Dec 12 19:04 mcGeant_t3.root
After the simulation ends, the thread-local files are empty, and the main file contains data from different ntuples stored in various backup cycles of the TTree:
root -l mcGeant.root
root [0]
Attaching file mcGeant.root as _file0...
(TFile *) 0x55e68bf1cf90
root [1] .ls
TFile** mcGeant.root
TFile* mcGeant.root
KEY: TTree T;5 My tree [current cycle]
KEY: TTree T;4 My tree [backup cycle]
KEY: TTree T;3 My tree [backup cycle]
KEY: TTree T;2 My tree [backup cycle]
KEY: TTree T;1 My tree [backup cycle]
I have in my app pretty standard of the MT-like function stack:
RunAction::RunAction():G4UserRunAction(){
m_AnalysisManager = G4AnalysisManager::Instance();
m_AnalysisManager->SetNtupleMerging(false);
m_AnalysisManager->SetVerboseLevel(2);
}
// _________________________________________________________
void RunAction::BeginOfRunAction(const G4Run* aRun){
m_AnalysisManager->OpenFile("mcGeant.root");
NTupleEventAnalisys::GetInstance()->CreateNTuple(aRun);
}
// _________________________________________________________
void RunAction::EndOfRunAction(const G4Run*){
m_AnalysisManager->Write();
m_AnalysisManager->CloseFile();
}
// _________________________________________________________
void EventAction::EndOfEventAction(const G4Event* anEvent){
NTupleEventAnalisys::GetInstance()->EndOfEventAction(anEvent)
}
// _________________________________________________________
void NTupleEventAnalisys::CreateNTuple(){
auto ntupleId = m_analysisManager->CreateNtuple("T","My tree");
m_ntupleId.Put(ntupleId); // G4Cache variable to keep it thread local
m_analysisManager->CreateNtupleIColumn(ntupleId, "G4EvtId");
m_analysisManager->CreateNtupleIColumn(ntupleId, "G4RunId");
m_analysisManager->FinishNtuple(ntupleId);
}
// _________________________________________________________
void NTupleEventAnalisys::EndOfEventAction(const G4Event *evt){
auto ntupleId = m_ntupleId.Get();
G4int dummyVal = 1;
m_analysisManager->FillNtupleIColumn(ntupleId,0, dummyVal);
m_analysisManager->FillNtupleIColumn(ntupleId,1, dummyVal);
m_analysisManager->AddNtupleRow(ntupleId);
}
Has anyone experienced something similar or have any insights on how to resolve this issue?
Geant4 Version: geant4-11-01-patch-01 [MT] (10-February-2023)