Skip to content

Commit e42624d

Browse files
committed
multithreading radioactive decays
1 parent c0fc4dd commit e42624d

File tree

9 files changed

+196
-213
lines changed

9 files changed

+196
-213
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
55
project(OMSim)
66
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
77

8+
# Add these lines for debug information
9+
set(CMAKE_BUILD_TYPE Debug)
10+
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g")
11+
812
# Option to build example with Geant4 UI and Vis drivers
913
option(WITH_GEANT4_UIVIS "Build example with Geant4 UI and Vis drivers" ON)
1014

common/framework/include/OMSimHitManager.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ public:
8282
std::vector<double> countHits(int pModuleIndex = 0);
8383
void setNumberOfPMTs(int pNumberOfPMTs, int pModuleIndex = 0);
8484
HitStats getHitsOfModule(int pModuleIndex = 0);
85+
HitStats getSingleThreadHitsOfModule(int pModuleIndex = 0);
86+
bool areThereHitsInModule(int pModuleIndex = 0);
8587
void sortHitStatsByTime(HitStats &pHits);
8688
std::vector<int> calculateMultiplicity(const G4double pTimeWindow, int pModuleNumber = 0);
8789
G4int getNextDetectorIndex() { return ++mCurrentIndex; }

common/framework/src/OMSimHitManager.cc

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ void OMSimHitManager::setNumberOfPMTs(int pNumberOfPMTs, int pModuleIndex)
131131
}
132132

133133
/**
134-
* @brief Retrieves the HitStats structure for the specified module.
134+
* @brief Retrieves the HitStats structure for the specified module, should be called after data between threads was merged. @see mergeThreadData
135135
* @param moduleIndex Index of the module for which to retrieve hit statistics. Default is 0.
136136
* @return A HitStats structure containing hit information of specified module.
137137
*/
@@ -140,6 +140,24 @@ HitStats OMSimHitManager::getHitsOfModule(int pModuleIndex)
140140
return mModuleHits[pModuleIndex];
141141
}
142142

143+
/**
144+
* @brief Retrieves the HitStats structure for the specified module of single thread.
145+
* @param moduleIndex Index of the module for which to retrieve hit statistics. Default is 0.
146+
* @return A HitStats structure containing hit information of specified module.
147+
*/
148+
HitStats OMSimHitManager::getSingleThreadHitsOfModule(int pModuleIndex)
149+
{
150+
log_debug("Getting mThreadData of thread {}", G4Threading::G4GetThreadId());
151+
return mThreadData->moduleHits[pModuleIndex];
152+
}
153+
154+
155+
bool OMSimHitManager::areThereHitsInModule(int pModuleIndex)
156+
{
157+
if (!mThreadData) {return false;};
158+
return mThreadData->moduleHits.find(pModuleIndex) != mThreadData->moduleHits.end();
159+
}
160+
143161
/**
144162
* @brief Deletes hit information in memory for all modules.
145163
*/
@@ -154,6 +172,7 @@ void OMSimHitManager::reset()
154172
delete mThreadData;
155173
mThreadData = nullptr;
156174
}
175+
log_trace("Finished reseting hit manager");
157176
}
158177

159178
/**
Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/**
1+
/**
22
* @file OMSimAngularAnalysis.hh
33
* @brief Defines the OMSimEffectiveAreaAnalyisis class for calculating effective area and writing results to output file.
44
* @ingroup EffectiveArea
@@ -15,12 +15,13 @@
1515
/**
1616
* @brief Struct to hold results of effective area calculations.
1717
*/
18-
struct effectiveAreaResult {
19-
double EA; ///< Effective area.
18+
struct effectiveAreaResult
19+
{
20+
double EA; ///< Effective area.
2021
double EAError; ///< Uncertainty of effective area.
2122
};
2223

23-
/**
24+
/**
2425
* @class OMSimEffectiveAreaAnalyisis
2526
* @brief Responsible for calculating the effective area of optical hits and saving the results.
2627
* @ingroup EffectiveArea
@@ -31,64 +32,62 @@ public:
3132
OMSimEffectiveAreaAnalyisis(){};
3233
~OMSimEffectiveAreaAnalyisis(){};
3334

34-
template<typename... Args>
35-
void writeScan(Args... args);
36-
template<typename... Args>
37-
void writeHeader(Args... args);
35+
template <typename... Args>
36+
void writeScan(Args... args);
37+
template <typename... Args>
38+
void writeHeader(Args... args);
3839

3940
effectiveAreaResult calculateEffectiveArea(double pHits);
40-
4141
G4String mOutputFileName;
42-
std::fstream mDatafile;
43-
private:
44-
4542
};
4643

4744
/**
4845
* @brief Writes a scan result to the output file.
4946
* @param args The values to be written to the output file.
5047
*/
51-
template<typename... Args>
52-
void OMSimEffectiveAreaAnalyisis::writeScan(Args... args) {
48+
template <typename... Args>
49+
void OMSimEffectiveAreaAnalyisis::writeScan(Args... args)
50+
{
5351
std::vector<double> lHits = OMSimHitManager::getInstance().countHits();
54-
mDatafile.open(mOutputFileName.c_str(), std::ios::out | std::ios::app);
5552

56-
// Write all arguments to the file
57-
((mDatafile << args << "\t"), ...);
53+
std::fstream lDataFile;
54+
lDataFile.open(mOutputFileName.c_str(), std::ios::out | std::ios::app);
5855

56+
// Write all arguments to the file
57+
((lDataFile << args << "\t"), ...);
5958

6059
G4double lTotalHits = 0;
61-
for (const auto &hit : lHits) {
62-
mDatafile << hit << "\t";
60+
for (const auto &hit : lHits)
61+
{
62+
lDataFile << hit << "\t";
6363
lTotalHits = hit; // last element is total nr of hits
6464
}
6565

6666
effectiveAreaResult lEffectiveArea = calculateEffectiveArea(lTotalHits);
67-
mDatafile << lEffectiveArea.EA << "\t" << lEffectiveArea.EAError << "\t";
68-
mDatafile << G4endl;
69-
mDatafile.close();
67+
lDataFile << lEffectiveArea.EA << "\t" << lEffectiveArea.EAError << "\t";
68+
lDataFile << G4endl;
69+
lDataFile.close();
7070
}
7171

72-
7372
/**
7473
* @brief Writes the header line to the output file.
7574
*/
76-
template<typename... Args>
75+
template <typename... Args>
7776
void OMSimEffectiveAreaAnalyisis::writeHeader(Args... args)
7877
{
79-
mDatafile.open(mOutputFileName.c_str(), std::ios::out | std::ios::app);
80-
mDatafile << "# ";
81-
((mDatafile << args << "\t"), ...);
82-
mDatafile << "hits[1perPMT]"
83-
<< "\t"
84-
<< "total_hits"
85-
<< "\t"
86-
<< "EA_Total(cm^2)"
87-
<< "\t"
88-
<< "EA_Total_error(cm^2)"
89-
<< "\t" << G4endl;
90-
mDatafile.close();
78+
std::fstream lDataFile;
79+
lDataFile.open(mOutputFileName.c_str(), std::ios::out | std::ios::app);
80+
lDataFile << "# ";
81+
((lDataFile << args << "\t"), ...);
82+
lDataFile << "hits[1perPMT]"
83+
<< "\t"
84+
<< "total_hits"
85+
<< "\t"
86+
<< "EA_Total(cm^2)"
87+
<< "\t"
88+
<< "EA_Total_error(cm^2)"
89+
<< "\t" << G4endl;
90+
lDataFile.close();
9191
}
9292

93-
9493
#endif

radioactive_decays/include/OMSimDecaysAnalysis.hh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ public:
3737
void appendDecay(G4String pParticleName, G4double pDecayTime, G4ThreeVector pDecayPosition);
3838
void mergeDecayData();
3939
void writeMultiplicity();
40-
void writeDecayInformation();
41-
void writeHitInformation();
40+
void writeThreadDecayInformation();
41+
void writeThreadHitInformation();
4242
void reset();
4343

4444
private:
@@ -47,7 +47,6 @@ private:
4747

4848
static G4Mutex mMutex;
4949

50-
std::fstream mDatafile;
5150
static OMSimDecaysAnalysis* mInstance;
5251
OMSimDecaysAnalysis() = default;
5352
~OMSimDecaysAnalysis() = default;

radioactive_decays/src/OMSimDecaysAnalysis.cc

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -63,73 +63,84 @@ void OMSimDecaysAnalysis::writeMultiplicity()
6363
G4String lMultiplicityFileName = lOutputSuffix + "_" + getThreadIDStr() + "_multiplicity.dat";
6464

6565
std::vector<int> lMultiplicity = OMSimHitManager::getInstance().calculateMultiplicity(20 * ns);
66-
mDatafile.open(lMultiplicityFileName.c_str(), std::ios::out | std::ios::app);
66+
67+
std::fstream lDatafile;
68+
lDatafile.open(lMultiplicityFileName.c_str(), std::ios::out | std::ios::app);
6769

6870
for (const auto &value : lMultiplicity)
6971
{
70-
mDatafile << value << "\t";
72+
lDatafile << value << "\t";
7173
}
72-
mDatafile << G4endl;
73-
mDatafile.close();
74+
lDatafile << G4endl;
75+
lDatafile.close();
7476
}
7577

7678
/**
7779
* @brief Write isotoped related data to the output file.
7880
*/
79-
void OMSimDecaysAnalysis::writeDecayInformation()
81+
void OMSimDecaysAnalysis::writeThreadDecayInformation()
8082
{
83+
log_trace("Writing decay information of {} decays", mThreadDecayStats->eventId.size());
84+
8185
G4String lOutputSuffix = OMSimCommandArgsTable::getInstance().get<std::string>("output_file");
8286
G4String lDecaysFileName = lOutputSuffix + "_" + getThreadIDStr() + "_decays.dat";
8387

84-
mDatafile.open(lDecaysFileName.c_str(), std::ios::out | std::ios::app);
88+
std::fstream lDatafile;
89+
lDatafile.open(lDecaysFileName.c_str(), std::ios::out | std::ios::app);
8590
if (mThreadDecayStats->eventId.size() > 0)
8691
{
8792
for (int i = 0; i < (int)mThreadDecayStats->eventId.size(); i++)
8893
{
89-
mDatafile << mThreadDecayStats->eventId.at(i) << "\t";
90-
mDatafile << std::setprecision(13);
91-
mDatafile << mThreadDecayStats->decay_time.at(i) << "\t";
92-
mDatafile << std::setprecision(4);
93-
mDatafile << mThreadDecayStats->isotope_name.at(i) << "\t";
94-
mDatafile << mThreadDecayStats->decay_position.at(i).x() << "\t";
95-
mDatafile << mThreadDecayStats->decay_position.at(i).y() << "\t";
96-
mDatafile << mThreadDecayStats->decay_position.at(i).z() << "\t";
97-
mDatafile << G4endl;
94+
lDatafile << mThreadDecayStats->eventId.at(i) << "\t";
95+
lDatafile << std::setprecision(13);
96+
lDatafile << mThreadDecayStats->decay_time.at(i) << "\t";
97+
lDatafile << std::setprecision(4);
98+
lDatafile << mThreadDecayStats->isotope_name.at(i) << "\t";
99+
lDatafile << mThreadDecayStats->decay_position.at(i).x() << "\t";
100+
lDatafile << mThreadDecayStats->decay_position.at(i).y() << "\t";
101+
lDatafile << mThreadDecayStats->decay_position.at(i).z() << "\t";
102+
lDatafile << G4endl;
98103
}
99104
}
100-
mDatafile.close();
105+
lDatafile.close();
106+
log_trace("Finished writing decay information");
101107
}
102108

103109
/**
104110
* @brief Write data of the hits to the output file.
105111
*/
106-
void OMSimDecaysAnalysis::writeHitInformation()
112+
void OMSimDecaysAnalysis::writeThreadHitInformation()
107113
{
108-
HitStats lHits = OMSimHitManager::getInstance().getHitsOfModule();
114+
if (!OMSimHitManager::getInstance().areThereHitsInModule()) return;
115+
116+
HitStats lHits = OMSimHitManager::getInstance().getSingleThreadHitsOfModule();
109117
G4String lOutputSuffix = OMSimCommandArgsTable::getInstance().get<std::string>("output_file");
110118
G4String lHitsFileName = lOutputSuffix + "_" + getThreadIDStr() + "_hits.dat";
119+
log_trace("Writing hit information of {} hits", lHits.eventId.size());
111120

112-
mDatafile.open(lHitsFileName.c_str(), std::ios::out | std::ios::app);
121+
std::fstream lDatafile;
122+
lDatafile.open(lHitsFileName.c_str(), std::ios::out | std::ios::app);
113123
if (lHits.eventId.size() > 0)
114124
{
115125
for (int i = 0; i < (int)lHits.eventId.size(); i++)
116126
{
117-
mDatafile << lHits.eventId.at(i) << "\t";
118-
mDatafile << std::setprecision(13);
119-
mDatafile << lHits.hitTime.at(i) / s << "\t";
120-
mDatafile << std::setprecision(4);
121-
mDatafile << lHits.PMTnr.at(i) << "\t";
122-
mDatafile << lHits.energy.at(i) << "\t";
123-
mDatafile << lHits.globalPosition.at(i).x() << "\t";
124-
mDatafile << lHits.globalPosition.at(i).y() << "\t";
125-
mDatafile << lHits.globalPosition.at(i).z() << "\t";
126-
mDatafile << lHits.PMTresponse.at(i).PE << "\t";
127-
mDatafile << lHits.PMTresponse.at(i).transitTime << "\t";
128-
mDatafile << lHits.PMTresponse.at(i).detectionProbability << "\t";
129-
mDatafile << G4endl;
127+
lDatafile << lHits.eventId.at(i) << "\t";
128+
lDatafile << std::setprecision(13);
129+
lDatafile << lHits.hitTime.at(i) / s << "\t";
130+
lDatafile << std::setprecision(4);
131+
lDatafile << lHits.PMTnr.at(i) << "\t";
132+
lDatafile << lHits.energy.at(i) << "\t";
133+
lDatafile << lHits.globalPosition.at(i).x() << "\t";
134+
lDatafile << lHits.globalPosition.at(i).y() << "\t";
135+
lDatafile << lHits.globalPosition.at(i).z() << "\t";
136+
lDatafile << lHits.PMTresponse.at(i).PE << "\t";
137+
lDatafile << lHits.PMTresponse.at(i).transitTime << "\t";
138+
lDatafile << lHits.PMTresponse.at(i).detectionProbability << "\t";
139+
lDatafile << G4endl;
130140
}
131141
}
132-
mDatafile.close();
142+
lDatafile.close();
143+
log_trace("Finished writing detailed hit information");
133144
}
134145

135146
/**

radioactive_decays/src/OMSimEventAction.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ void OMSimEventAction::EndOfEventAction(const G4Event *evt)
3131
if (!lArgs.get<bool>("multiplicity_study"))
3232
{
3333
log_debug("End of event, saving information and reseting (thread {})", G4Threading::G4GetThreadId());
34-
lAnalysisManager.writeHitInformation();
35-
lAnalysisManager.writeDecayInformation();
34+
lAnalysisManager.writeThreadHitInformation();
35+
lAnalysisManager.writeThreadDecayInformation();
3636
lHitManager.reset();
3737
lAnalysisManager.reset();
3838
}

0 commit comments

Comments
 (0)