Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/parallel/ThreadsafeScorers/src/TSRun.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 "TSDetectorConstruction.hh"
 74 
 75 #include "G4MultiFunctionalDetector.hh"
 76 #include "G4SDManager.hh"
 77 #include "G4VPrimitiveScorer.hh"
 78 
 79 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 80 
 81 std::vector<G4TAtomicHitsMap<G4double>*> TSRun::fAtomicRunMaps;
 82 
 83 std::map<G4String, TSRun::MutexHitsMap_t> TSRun::fMutexRunMaps;
 84 
 85 std::vector<G4StatContainer<G4ConvergenceTester>*> TSRun::fConvMaps;
 86 
 87 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 88 
 89 TSRun::TSRun(const G4String& mfd_name) : G4Run()
 90 {
 91   ConstructMFD(mfd_name);
 92 }
 93 
 94 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 95 
 96 TSRun::~TSRun()
 97 {
 98   //--- Clear HitsMap for RUN
 99   for (unsigned i = 0; i < fRunMaps.size(); ++i)
100     delete fRunMaps[i];
101 
102   if (!G4Threading::IsWorkerThread()) {
103     for (unsigned i = 0; i < fAtomicRunMaps.size(); ++i)
104       delete fAtomicRunMaps[i];
105 
106     for (auto& itr : fConvMaps)
107       delete itr;
108 
109     fAtomicRunMaps.clear();
110     fMutexRunMaps.clear();
111     fConvMaps.clear();
112   }
113 }
114 
115 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
116 
117 //    clear all data members.
118 void TSRun::ConstructMFD(const G4String& mfdName)
119 {
120   G4SDManager* SDman = G4SDManager::GetSDMpointer();
121   //=================================================
122   //  Initalize RunMaps for accumulation.
123   //  Get CollectionIDs for HitCollections.
124   //=================================================
125   G4MultiFunctionalDetector* mfd =
126     (G4MultiFunctionalDetector*)(SDman->FindSensitiveDetector(mfdName));
127   //
128   if (mfd) {
129     //--- Loop over the registered primitive scorers.
130     for (G4int icol = 0; icol < mfd->GetNumberOfPrimitives(); icol++) {
131       // Get Primitive Scorer object.
132       G4VPrimitiveScorer* scorer = mfd->GetPrimitive(icol);
133       // collection name and collectionID for HitsCollection,
134       // where type of HitsCollection is G4THitsMap in case
135       // of primitive scorer.
136       // The collection name is given by <MFD name>/<Primitive
137       // Scorer name>.
138       G4String collectionName = scorer->GetName();
139       G4String fullCollectionName = mfdName + "/" + collectionName;
140       G4int collectionID = SDman->GetCollectionID(fullCollectionName);
141       //
142       if (collectionID >= 0) {
143         G4cout << "++ " << fullCollectionName << " id " << collectionID << G4endl;
144         // Store obtained HitsCollection information into data members.
145         // And, creates new G4THitsMap for accumulating quantities during RUN.
146         fCollNames.push_back(fullCollectionName);
147         fCollIDs.push_back(collectionID);
148         fRunMaps.push_back(new G4THitsMap<G4double>(mfdName, collectionName));
149         fStatMaps.push_back(new G4StatContainer<G4StatAnalysis>(
150           mfdName, collectionName, TSDetectorConstruction::Instance()->GetTotalTargets()));
151         if (!G4Threading::IsWorkerThread()) {
152           fAtomicRunMaps.push_back(new G4TAtomicHitsMap<G4double>(mfdName, collectionName));
153           fMutexRunMaps[fCollNames[collectionID]].clear();
154           fConvMaps.push_back(new G4StatContainer<G4ConvergenceTester>(
155             mfdName, collectionName, TSDetectorConstruction::Instance()->GetTotalTargets()));
156         }
157       }
158       else {
159         G4cout << "** collection " << fullCollectionName << " not found. " << G4endl;
160       }
161     }
162   }
163 }
164 
165 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
166 //
167 //  RecordEvent is called at end of event.
168 //  For scoring purpose, the resultant quantity in a event,
169 //  is accumulated during a TSRun.
170 void TSRun::RecordEvent(const G4Event* aEvent)
171 {
172   G4Run::RecordEvent(aEvent);
173 
174   //=============================
175   // HitsCollection of This Event
176   //============================
177   G4HCofThisEvent* HCE = aEvent->GetHCofThisEvent();
178   if (!HCE) return;
179 
180   for (unsigned i = 0; i < fCollIDs.size(); ++i) {
181     G4int fCollID = fCollIDs.at(i);
182     //=======================================================
183     // Sum up HitsMap of this Event into HitsMap of this RUN
184     //=======================================================
185     G4THitsMap<G4double>* EvtMap = 0;
186     if (fCollID >= 0)  // Collection is attached to HCE
187       EvtMap = static_cast<G4THitsMap<G4double>*>(HCE->GetHC(fCollID));
188     else
189       G4cout << " Error EvtMap Not Found " << G4endl;
190 
191     if (EvtMap) {
192       //=== Sum up HitsMap of this event to HitsMap of RUN.===
193       {
194         *fRunMaps[fCollID] += *EvtMap;
195       }
196       //=== Sum up HitsMap of this event to StatMap of RUN.===
197       {
198         // G4StatAnalysis map
199         *fStatMaps[fCollID] += *EvtMap;
200       }
201       //=== Sum up HitsMap of this event to atomic HitsMap of RUN.===
202       {
203         *fAtomicRunMaps[fCollID] += *EvtMap;
204       }
205       //=== Sum up HitsMap of this event to MutexMap of RUN.===
206       {
207         // mutex run map
208         static G4Mutex mtx = G4MUTEX_INITIALIZER;
209         G4AutoLock lock(&mtx);
210         for (const auto& itr : *EvtMap)
211           fMutexRunMaps[fCollNames[fCollID]][itr.first] += *itr.second;
212       }
213       //=== Sum up HitsMap of this event to MutexMap of RUN.===
214       {
215         // G4ConvergenceTester run map
216         static G4Mutex mtx = G4MUTEX_INITIALIZER;
217         G4AutoLock lock(&mtx);
218         *fConvMaps[fCollID] += *EvtMap;
219       }
220     }
221   }
222 }
223 
224 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
225 
226 // Merge hits map from threads
227 void TSRun::Merge(const G4Run* aTSRun)
228 {
229   const TSRun* localTSRun = static_cast<const TSRun*>(aTSRun);
230 
231   for (unsigned i = 0; i < fRunMaps.size(); ++i) {
232     *fRunMaps[i] += *localTSRun->fRunMaps[i];
233     *fStatMaps[i] += *localTSRun->fStatMaps[i];
234   }
235 
236   G4Run::Merge(aTSRun);
237 }
238 
239 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
240 
241 // Access HitsMap.
242 // by full description of collection name, that is
243 // <MultiFunctional Detector Name>/<Primitive Scorer Name>
244 G4THitsMap<G4double>* TSRun::GetHitsMap(const G4String& collName) const
245 {
246   for (unsigned i = 0; i < fCollNames.size(); ++i) {
247     if (collName == fCollNames[i]) return fRunMaps[i];
248   }
249 
250   G4Exception("TSRun", collName.c_str(), JustWarning,
251               "GetHitsMap failed to locate the requested HitsMap");
252   return nullptr;
253 }
254 
255 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
256 
257 // Access AtomicsHitsMap.
258 // by full description of collection name, that is
259 // <MultiFunctional Detector Name>/<Primitive Scorer Name>
260 G4TAtomicHitsMap<G4double>* TSRun::GetAtomicHitsMap(const G4String& collName) const
261 {
262   for (unsigned i = 0; i < fCollNames.size(); ++i) {
263     if (collName == fCollNames[i]) return fAtomicRunMaps[i];
264   }
265 
266   G4Exception("TSRun", collName.c_str(), JustWarning,
267               "GetHitsMap failed to locate the requested AtomicHitsMap");
268   return nullptr;
269 }
270 
271 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
272 
273 // Access AtomicsHitsMap.
274 // by full description of collection name, that is
275 // <MultiFunctional Detector Name>/<Primitive Scorer Name>
276 TSRun::MutexHitsMap_t* TSRun::GetMutexHitsMap(const G4String& collName) const
277 {
278   if (fMutexRunMaps.find(collName) != fMutexRunMaps.end()) return &fMutexRunMaps[collName];
279 
280   G4Exception("TSRun", collName.c_str(), JustWarning,
281               "GetHitsMap failed to locate the requested MutexHitsMap");
282   return nullptr;
283 }
284 
285 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
286 
287 // Access StatMap.
288 // by full description of collection name, that is
289 // <MultiFunctional Detector Name>/<Primitive Scorer Name>
290 G4StatContainer<G4StatAnalysis>* TSRun::GetStatMap(const G4String& collName) const
291 {
292   for (unsigned i = 0; i < fCollNames.size(); ++i) {
293     if (collName == fCollNames[i]) return fStatMaps[i];
294   }
295 
296   G4Exception("TSRun", collName.c_str(), JustWarning,
297               "GetStatMap failed to locate the requested StatMap");
298   return nullptr;
299 }
300 
301 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
302 
303 G4StatContainer<G4ConvergenceTester>* TSRun::GetConvMap(const G4String& collName) const
304 {
305   for (unsigned i = 0; i < fCollNames.size(); ++i) {
306     if (collName == fCollNames[i]) return fConvMaps[i];
307   }
308 
309   G4Exception("TSRun", collName.c_str(), JustWarning,
310               "GetHitsMap failed to locate the requested AtomicHitsMap");
311   return nullptr;
312 }
313