Skip to content

Commit 28d4baf

Browse files
committed
hitmanager multithread safe
1 parent d0abceb commit 28d4baf

File tree

2 files changed

+93
-27
lines changed

2 files changed

+93
-27
lines changed

common/framework/include/OMSimHitManager.hh

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
#include <G4ThreeVector.hh>
1919
#include <fstream>
20+
#include <G4AutoLock.hh>
21+
#include <G4Threading.hh>
2022

2123
/**
2224
* @struct HitStats
@@ -59,15 +61,9 @@ class OMSimHitManager
5961
OMSimHitManager &operator=(const OMSimHitManager &) = delete;
6062

6163
public:
62-
/**
63-
* @brief Returns the singleton instance of the OMSimHitManager.
64-
* @return A reference to the singleton instance.
65-
*/
66-
static OMSimHitManager &getInstance()
67-
{
68-
static OMSimHitManager instance;
69-
return instance;
70-
}
64+
65+
66+
static OMSimHitManager& getInstance();
7167

7268
void appendHitInfo(
7369
G4double pGlobalTime,
@@ -88,13 +84,23 @@ public:
8884
HitStats getHitsOfModule(int pModuleIndex = 0);
8985
void sortHitStatsByTime(HitStats &pHits);
9086
std::vector<int> calculateMultiplicity(const G4double pTimeWindow, int pModuleNumber = 0);
91-
std::map<G4int, HitStats> mModuleHits; ///< Map of a HitStats containing hit information for each simulated optical module
92-
9387
G4int getNextDetectorIndex() { return ++mCurrentIndex; }
88+
void mergeThreadData();
89+
90+
std::map<G4int, HitStats> mModuleHits; ///< Map of a HitStats containing hit information for each simulated optical module
9491

9592
private:
9693
std::map<G4int, G4int> mNumPMTs; ///< Map of number of PMTs in the used optical modules
9794
G4int mCurrentIndex = -1;
95+
96+
static G4Mutex mMutex;
97+
static OMSimHitManager* mInstance;
98+
99+
struct ThreadLocalData {
100+
std::map<G4int, HitStats> moduleHits;
101+
};
102+
G4ThreadLocal static ThreadLocalData* mThreadData;
103+
G4bool mDataWasMerged = false;
98104
};
99105

100106
#endif

common/framework/src/OMSimHitManager.cc

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,27 @@
55

66
#include <numeric>
77

8+
G4Mutex OMSimHitManager::mMutex = G4Mutex();
9+
OMSimHitManager *OMSimHitManager::mInstance = nullptr;
10+
G4ThreadLocal OMSimHitManager::ThreadLocalData *OMSimHitManager::mThreadData = nullptr;
11+
12+
/**
13+
* @brief Returns the singleton instance of the OMSimHitManager.
14+
* @return A reference to the singleton instance.
15+
*/
16+
OMSimHitManager &OMSimHitManager::getInstance()
17+
{
18+
if (!mInstance)
19+
{
20+
G4AutoLock lock(&mMutex);
21+
if (!mInstance)
22+
{
23+
mInstance = new OMSimHitManager();
24+
}
25+
}
26+
return *mInstance;
27+
}
28+
829
/**
930
* @brief Applies a given permutation to a container.
1031
*
@@ -21,7 +42,7 @@ void applyPermutation(std::vector<T> &pVec, const std::vector<std::size_t> &pPer
2142
for (std::size_t i = 0; i < pVec.size(); ++i)
2243
{
2344
if (lDone[i])
24-
continue; // Skip the item if it's already in place.
45+
continue; // Skip the item if it's already in place.
2546
lDone[i] = true; // Mark the item as placed.
2647
std::size_t prev_j = i;
2748
std::size_t j = pPermutation[i];
@@ -66,24 +87,29 @@ void OMSimHitManager::appendHitInfo(
6687
OMSimPMTResponse::PMTPulse pResponse,
6788
G4int pModuleNumber)
6889
{
69-
// Check if the module exists in the map
70-
if (mModuleHits.find(pModuleNumber) == mModuleHits.end())
90+
if (!mThreadData)
91+
{
92+
mThreadData = new ThreadLocalData();
93+
}
94+
95+
// Check if the module exists in the thread-local map
96+
if (mThreadData->moduleHits.find(pModuleNumber) == mThreadData->moduleHits.end())
7197
{
7298
// Create a new HitStats for this module
73-
mModuleHits[pModuleNumber] = HitStats();
99+
mThreadData->moduleHits[pModuleNumber] = HitStats();
74100
}
75-
G4int lEventID = EventInfoManager::getInstance().getCurrentEventID();
76-
mModuleHits[pModuleNumber].eventId.push_back(lEventID);
77-
mModuleHits[pModuleNumber].hitTime.push_back(pGlobalTime);
78-
mModuleHits[pModuleNumber].flightTime.push_back(pLocalTime);
79-
mModuleHits[pModuleNumber].pathLenght.push_back(pTrackLength);
80-
mModuleHits[pModuleNumber].energy.push_back(pEnergy);
81-
mModuleHits[pModuleNumber].PMTnr.push_back(pPMTHitNumber);
82-
mModuleHits[pModuleNumber].direction.push_back(pMomentumDirection);
83-
mModuleHits[pModuleNumber].globalPosition.push_back(pGlobalPos);
84-
mModuleHits[pModuleNumber].localPosition.push_back(pLocalPos);
85-
mModuleHits[pModuleNumber].generationDetectionDistance.push_back(pDistance);
86-
mModuleHits[pModuleNumber].PMTresponse.push_back(pResponse);
101+
auto &moduleHits = mThreadData->moduleHits[pModuleNumber];
102+
moduleHits.eventId.push_back(EventInfoManager::getInstance().getCurrentEventID());
103+
moduleHits.hitTime.push_back(pGlobalTime);
104+
moduleHits.flightTime.push_back(pLocalTime);
105+
moduleHits.pathLenght.push_back(pTrackLength);
106+
moduleHits.energy.push_back(pEnergy);
107+
moduleHits.PMTnr.push_back(pPMTHitNumber);
108+
moduleHits.direction.push_back(pMomentumDirection);
109+
moduleHits.globalPosition.push_back(pGlobalPos);
110+
moduleHits.localPosition.push_back(pLocalPos);
111+
moduleHits.generationDetectionDistance.push_back(pDistance);
112+
moduleHits.PMTresponse.push_back(pResponse);
87113
}
88114

89115
/**
@@ -113,6 +139,11 @@ HitStats OMSimHitManager::getHitsOfModule(int pModuleIndex)
113139
void OMSimHitManager::reset()
114140
{
115141
mModuleHits.clear();
142+
143+
if (mThreadData)
144+
{
145+
mThreadData->moduleHits.clear();
146+
}
116147
}
117148

118149
/**
@@ -123,6 +154,7 @@ void OMSimHitManager::reset()
123154
std::vector<double> OMSimHitManager::countHits(int pModuleIndex)
124155
{
125156
log_debug("Counting number of detected photons in module with index {}", pModuleIndex);
157+
if (!mDataWasMerged){mergeThreadData();};
126158
HitStats lHitsOfModule = mModuleHits[pModuleIndex];
127159
G4int lNumberPMTs = mNumPMTs[pModuleIndex];
128160

@@ -187,6 +219,8 @@ void OMSimHitManager::sortHitStatsByTime(HitStats &lHits)
187219
std::vector<int> OMSimHitManager::calculateMultiplicity(const G4double pTimeWindow, int pModuleIndex)
188220
{
189221
log_debug("Calculating multiplicity in time window {} for module with index", pTimeWindow, pModuleIndex);
222+
if (!mDataWasMerged){mergeThreadData();};
223+
190224
HitStats lHitsOfModule = mModuleHits[pModuleIndex];
191225
G4int lNumberPMTs = mNumPMTs[pModuleIndex];
192226

@@ -230,4 +264,30 @@ std::vector<int> OMSimHitManager::calculateMultiplicity(const G4double pTimeWind
230264
lMultiplicity[lCurrentSum - 1] += 1;
231265
}
232266
return lMultiplicity;
267+
}
268+
269+
void OMSimHitManager::mergeThreadData()
270+
{
271+
G4AutoLock lock(&mMutex);
272+
if (mThreadData)
273+
{
274+
for (const auto &[moduleIndex, hits] : mThreadData->moduleHits)
275+
{
276+
auto &globalHits = mModuleHits[moduleIndex];
277+
globalHits.eventId.insert(globalHits.eventId.end(), hits.eventId.begin(), hits.eventId.end());
278+
globalHits.hitTime.insert(globalHits.hitTime.end(), hits.hitTime.begin(), hits.hitTime.end());
279+
globalHits.flightTime.insert(globalHits.flightTime.end(), hits.flightTime.begin(), hits.flightTime.end());
280+
globalHits.pathLenght.insert(globalHits.pathLenght.end(), hits.pathLenght.begin(), hits.pathLenght.end());
281+
globalHits.energy.insert(globalHits.energy.end(), hits.energy.begin(), hits.energy.end());
282+
globalHits.PMTnr.insert(globalHits.PMTnr.end(), hits.PMTnr.begin(), hits.PMTnr.end());
283+
globalHits.direction.insert(globalHits.direction.end(), hits.direction.begin(), hits.direction.end());
284+
globalHits.localPosition.insert(globalHits.localPosition.end(), hits.localPosition.begin(), hits.localPosition.end());
285+
globalHits.globalPosition.insert(globalHits.globalPosition.end(), hits.globalPosition.begin(), hits.globalPosition.end());
286+
globalHits.generationDetectionDistance.insert(globalHits.generationDetectionDistance.end(), hits.generationDetectionDistance.begin(), hits.generationDetectionDistance.end());
287+
globalHits.PMTresponse.insert(globalHits.PMTresponse.end(), hits.PMTresponse.begin(), hits.PMTresponse.end());
288+
}
289+
delete mThreadData;
290+
mThreadData = nullptr;
291+
}
292+
mDataWasMerged = true;
233293
}

0 commit comments

Comments
 (0)