Loading...
Searching...
No Matches
TSRun.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26/// \file parallel/ThreadsafeScorers/src/TSRun.cc
27/// \brief Implementation of the TSRun class
28//
29//
30//
31//
32/// TSRun contains five hits collections types:
33/// 1) a thread-local hits map,
34/// 2) a global atomic hits map
35/// 3) a global "mutex" hits map
36/// 4) a global G4StatAnalysis hits deque
37/// 5) a global G4ConvergenceTester hits deque
38///
39/// The thread-local hits map is the same as you will find in many other
40/// examples.
41///
42/// The atomics hits map is the purpose of this example. Code-wise, the
43/// implementation looks extremely similar to the thread-local version with
44/// 3 primary exceptions:
45/// (1) construction - there should only be one instance so it should be a
46/// static member variable or a pointer/reference to a single instance
47/// (2) It does not need to, nor should be, summed in G4Run::Merge()
48/// (3) destruction -- it should only be cleared by the master thread since
49/// there is only one instance.
50///
51/// The "mutex" hits map is also included as reference for checking the results
52/// accumulated by the thread-local hits maps and atomic hits maps. The
53/// differences w.r.t. this hits maps are computed in
54/// TSRunAction::EndOfRunAction
55///
56/// The "G4StatAnalysis" and "G4ConvergenceTester" hits deques are
57/// memory-efficient version of the standard G4THitsMap. While maps are
58/// ideal for scoring at the G4Event-level, where sparsity w.r.t. indices
59/// is common; at the G4Run-level, these data structures require much
60/// less memory overhead. Due to a lack of
61/// G4ConvergenceTester::operator+=(G4ConvergenceTester), the static version
62/// of G4ConvergenceTester is the only valid way to use G4ConvergenceTester
63/// in a scoring container. This is not the case for G4StatAnalysis, which
64/// can be used in lieu of G4double.
65///
66//
67//
68//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
69//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
70
71#include "TSRun.hh"
72
73#include "G4SDManager.hh"
74#include "G4MultiFunctionalDetector.hh"
75#include "G4VPrimitiveScorer.hh"
76#include "G4TiMemory.hh"
78
79//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
80
81std::vector<G4TAtomicHitsMap<G4double>*> TSRun::fAtomicRunMaps;
82
83std::map<G4String, TSRun::MutexHitsMap_t> TSRun::fMutexRunMaps;
84
85std::vector<G4StatContainer<G4ConvergenceTester>*> TSRun::fConvMaps;
86
87//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
88
89TSRun::TSRun(const G4String& mfd_name)
90 : G4Run()
91{
92 ConstructMFD(mfd_name);
93}
94
95//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
96
98{
99 //--- Clear HitsMap for RUN
100 for(unsigned i = 0; i < fRunMaps.size(); ++i)
101 delete fRunMaps[i];
102
103 if(!G4Threading::IsWorkerThread())
104 {
105 for(unsigned i = 0; i < fAtomicRunMaps.size(); ++i)
106 delete fAtomicRunMaps[i];
107
108 for(auto& itr : fConvMaps)
109 delete itr;
110
111 fAtomicRunMaps.clear();
112 fMutexRunMaps.clear();
113 fConvMaps.clear();
114 }
115}
116
117//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
118
119// clear all data members.
120void TSRun::ConstructMFD(const G4String& mfdName)
121{
122 G4SDManager* SDman = G4SDManager::GetSDMpointer();
123 //=================================================
124 // Initalize RunMaps for accumulation.
125 // Get CollectionIDs for HitCollections.
126 //=================================================
128 (G4MultiFunctionalDetector*) (SDman->FindSensitiveDetector(mfdName));
129 //
130 if(mfd)
131 {
132 //--- Loop over the registered primitive scorers.
133 for(G4int icol = 0; icol < mfd->GetNumberOfPrimitives(); icol++)
134 {
135 // Get Primitive Scorer object.
136 G4VPrimitiveScorer* scorer = mfd->GetPrimitive(icol);
137 // collection name and collectionID for HitsCollection,
138 // where type of HitsCollection is G4THitsMap in case
139 // of primitive scorer.
140 // The collection name is given by <MFD name>/<Primitive
141 // Scorer name>.
142 G4String collectionName = scorer->GetName();
143 G4String fullCollectionName = mfdName + "/" + collectionName;
144 G4int collectionID = SDman->GetCollectionID(fullCollectionName);
145 //
146 if(collectionID >= 0)
147 {
148 G4cout << "++ " << fullCollectionName << " id " << collectionID
149 << G4endl;
150 // Store obtained HitsCollection information into data members.
151 // And, creates new G4THitsMap for accumulating quantities during RUN.
152 fCollNames.push_back(fullCollectionName);
153 fCollIDs.push_back(collectionID);
154 fRunMaps.push_back(new G4THitsMap<G4double>(mfdName, collectionName));
156 mfdName, collectionName,
157 TSDetectorConstruction::Instance()->GetTotalTargets()));
158 if(!G4Threading::IsWorkerThread())
159 {
160 fAtomicRunMaps.push_back(
161 new G4TAtomicHitsMap<G4double>(mfdName, collectionName));
162 fMutexRunMaps[fCollNames[collectionID]].clear();
164 mfdName, collectionName,
165 TSDetectorConstruction::Instance()->GetTotalTargets()));
166 }
167 }
168 else
169 {
170 G4cout << "** collection " << fullCollectionName << " not found. "
171 << G4endl;
172 }
173 }
174 }
175}
176
177//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
178//
179// RecordEvent is called at end of event.
180// For scoring purpose, the resultant quantity in a event,
181// is accumulated during a TSRun.
182void TSRun::RecordEvent(const G4Event* aEvent)
183{
184 G4Run::RecordEvent(aEvent);
185
186 //=============================
187 // HitsCollection of This Event
188 //============================
189 G4HCofThisEvent* HCE = aEvent->GetHCofThisEvent();
190 if(!HCE)
191 return;
192
193 for(unsigned i = 0; i < fCollIDs.size(); ++i)
194 {
195 G4int fCollID = fCollIDs.at(i);
196 //=======================================================
197 // Sum up HitsMap of this Event into HitsMap of this RUN
198 //=======================================================
199 G4THitsMap<G4double>* EvtMap = 0;
200 if(fCollID >= 0) // Collection is attached to HCE
201 EvtMap = static_cast<G4THitsMap<G4double>*>(HCE->GetHC(fCollID));
202 else
203 G4cout << " Error EvtMap Not Found " << G4endl;
204
205 G4USER_SCOPED_PROFILE(fCollNames.at(i));
206 if(EvtMap)
207 {
208 //=== Sum up HitsMap of this event to HitsMap of RUN.===
209 {
210 G4USER_SCOPED_PROFILE("ThreadLocal");
211 *fRunMaps[fCollID] += *EvtMap;
212 }
213 //=== Sum up HitsMap of this event to StatMap of RUN.===
214 {
215 G4USER_SCOPED_PROFILE("ThreadLocal/G4StatAnalysis");
216 // G4StatAnalysis map
217 *fStatMaps[fCollID] += *EvtMap;
218 }
219 //=== Sum up HitsMap of this event to atomic HitsMap of RUN.===
220 {
221 G4USER_SCOPED_PROFILE("Global/Atomic");
222 *fAtomicRunMaps[fCollID] += *EvtMap;
223 }
224 //=== Sum up HitsMap of this event to MutexMap of RUN.===
225 {
226 G4USER_SCOPED_PROFILE("Global/Mutex");
227 // mutex run map
228 static G4Mutex mtx = G4MUTEX_INITIALIZER;
229 G4AutoLock lock(&mtx);
230 for(const auto& itr : *EvtMap)
231 fMutexRunMaps[fCollNames[fCollID]][itr.first] += *itr.second;
232 }
233 //=== Sum up HitsMap of this event to MutexMap of RUN.===
234 {
235 G4USER_SCOPED_PROFILE("Global/Mutex/G4ConvergenceTester");
236 // G4ConvergenceTester run map
237 static G4Mutex mtx = G4MUTEX_INITIALIZER;
238 G4AutoLock lock(&mtx);
239 *fConvMaps[fCollID] += *EvtMap;
240 }
241 }
242 }
243}
244
245//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
246
247// Merge hits map from threads
248void TSRun::Merge(const G4Run* aTSRun)
249{
250 const TSRun* localTSRun = static_cast<const TSRun*>(aTSRun);
251
252 for(unsigned i = 0; i < fRunMaps.size(); ++i)
253 {
254 *fRunMaps[i] += *localTSRun->fRunMaps[i];
255 *fStatMaps[i] += *localTSRun->fStatMaps[i];
256 }
257
258 G4Run::Merge(aTSRun);
259}
260
261//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
262
263// Access HitsMap.
264// by full description of collection name, that is
265// <MultiFunctional Detector Name>/<Primitive Scorer Name>
267{
268 for(unsigned i = 0; i < fCollNames.size(); ++i)
269 {
270 if(collName == fCollNames[i])
271 return fRunMaps[i];
272 }
273
274 G4Exception("TSRun", collName.c_str(), JustWarning,
275 "GetHitsMap failed to locate the requested HitsMap");
276 return nullptr;
277}
278
279//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
280
281// Access AtomicsHitsMap.
282// by full description of collection name, that is
283// <MultiFunctional Detector Name>/<Primitive Scorer Name>
285 const G4String& collName) const
286{
287 for(unsigned i = 0; i < fCollNames.size(); ++i)
288 {
289 if(collName == fCollNames[i])
290 return fAtomicRunMaps[i];
291 }
292
293 G4Exception("TSRun", collName.c_str(), JustWarning,
294 "GetHitsMap failed to locate the requested AtomicHitsMap");
295 return nullptr;
296}
297
298//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
299
300// Access AtomicsHitsMap.
301// by full description of collection name, that is
302// <MultiFunctional Detector Name>/<Primitive Scorer Name>
304{
305 if(fMutexRunMaps.find(collName) != fMutexRunMaps.end())
306 return &fMutexRunMaps[collName];
307
308 G4Exception("TSRun", collName.c_str(), JustWarning,
309 "GetHitsMap failed to locate the requested MutexHitsMap");
310 return nullptr;
311}
312
313//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
314
315// Access StatMap.
316// by full description of collection name, that is
317// <MultiFunctional Detector Name>/<Primitive Scorer Name>
319 const G4String& collName) const
320{
321 for(unsigned i = 0; i < fCollNames.size(); ++i)
322 {
323 if(collName == fCollNames[i])
324 return fStatMaps[i];
325 }
326
327 G4Exception("TSRun", collName.c_str(), JustWarning,
328 "GetStatMap failed to locate the requested StatMap");
329 return nullptr;
330}
331
332//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
333
335 const G4String& collName) const
336{
337 for(unsigned i = 0; i < fCollNames.size(); ++i)
338 {
339 if(collName == fCollNames[i])
340 return fConvMaps[i];
341 }
342
343 G4Exception("TSRun", collName.c_str(), JustWarning,
344 "GetHitsMap failed to locate the requested AtomicHitsMap");
345 return nullptr;
346}
Definition of the TSDetectorConstruction class.
Definition of the TSRun class.
G4THitsDeque< _Tp > G4StatContainer
Definition TSRun.hh:74
This is an implementation of G4THitsMap<T> where the underlying type is G4atomic<T>,...
static TSDetectorConstruction * Instance()
virtual ~TSRun()
Definition TSRun.cc:97
std::vector< G4String > fCollNames
Definition TSRun.hh:102
static std::map< G4String, MutexHitsMap_t > fMutexRunMaps
Definition TSRun.hh:107
MutexHitsMap_t * GetMutexHitsMap(const G4String &) const
Definition TSRun.cc:303
virtual void Merge(const G4Run *)
Definition TSRun.cc:248
G4TAtomicHitsMap< G4double > * GetAtomicHitsMap(const G4String &) const
Definition TSRun.cc:284
TSRun(const G4String &)
Definition TSRun.cc:89
G4StatContainer< G4StatAnalysis > * GetStatMap(const G4String &collname) const
Definition TSRun.cc:318
std::map< G4int, G4double > MutexHitsMap_t
Definition TSRun.hh:79
virtual void RecordEvent(const G4Event *)
Definition TSRun.cc:182
static std::vector< G4TAtomicHitsMap< G4double > * > fAtomicRunMaps
TSRun contains five hits collections types: 1) a thread-local hits map, 2) a global atomic hits map 3...
Definition TSRun.hh:106
std::vector< G4int > fCollIDs
Definition TSRun.hh:103
G4THitsMap< G4double > * GetHitsMap(const G4String &collname) const
Definition TSRun.cc:266
void ConstructMFD(const G4String &)
Definition TSRun.cc:120
std::vector< G4StatContainer< G4StatAnalysis > * > fStatMaps
Definition TSRun.hh:105
G4StatContainer< G4ConvergenceTester > * GetConvMap(const G4String &) const
Definition TSRun.cc:334
std::vector< G4THitsMap< G4double > * > fRunMaps
Definition TSRun.hh:104
static std::vector< G4StatContainer< G4ConvergenceTester > * > fConvMaps
Definition TSRun.hh:108

Applications | User Support | Publications | Collaboration