![]() |
|
|||
File indexing completed on 2025-02-23 09:22:30
0001 // 0002 // ******************************************************************** 0003 // * License and Disclaimer * 0004 // * * 0005 // * The Geant4 software is copyright of the Copyright Holders of * 0006 // * the Geant4 Collaboration. It is provided under the terms and * 0007 // * conditions of the Geant4 Software License, included in the file * 0008 // * LICENSE and available at http://cern.ch/geant4/license . These * 0009 // * include a list of copyright holders. * 0010 // * * 0011 // * Neither the authors of this software system, nor their employing * 0012 // * institutes,nor the agencies providing financial support for this * 0013 // * work make any representation or warranty, express or implied, * 0014 // * regarding this software system or assume any liability for its * 0015 // * use. Please see the license in the file LICENSE and URL above * 0016 // * for the full disclaimer and the limitation of liability. * 0017 // * * 0018 // * This code implementation is the result of the scientific and * 0019 // * technical work of the GEANT4 collaboration. * 0020 // * By using, copying, modifying or distributing the software (or * 0021 // * any work based on the software) you agree to acknowledge its * 0022 // * use in resulting scientific publications, and indicate your * 0023 // * acceptance of all terms of the Geant4 Software license. * 0024 // ******************************************************************** 0025 // 0026 /// \file parallel/ThreadsafeScorers/src/TSRun.cc 0027 /// \brief Implementation of the TSRun class 0028 // 0029 // 0030 // 0031 // 0032 /// TSRun contains five hits collections types: 0033 /// 1) a thread-local hits map, 0034 /// 2) a global atomic hits map 0035 /// 3) a global "mutex" hits map 0036 /// 4) a global G4StatAnalysis hits deque 0037 /// 5) a global G4ConvergenceTester hits deque 0038 /// 0039 /// The thread-local hits map is the same as you will find in many other 0040 /// examples. 0041 /// 0042 /// The atomics hits map is the purpose of this example. Code-wise, the 0043 /// implementation looks extremely similar to the thread-local version with 0044 /// 3 primary exceptions: 0045 /// (1) construction - there should only be one instance so it should be a 0046 /// static member variable or a pointer/reference to a single instance 0047 /// (2) It does not need to, nor should be, summed in G4Run::Merge() 0048 /// (3) destruction -- it should only be cleared by the master thread since 0049 /// there is only one instance. 0050 /// 0051 /// The "mutex" hits map is also included as reference for checking the results 0052 /// accumulated by the thread-local hits maps and atomic hits maps. The 0053 /// differences w.r.t. this hits maps are computed in 0054 /// TSRunAction::EndOfRunAction 0055 /// 0056 /// The "G4StatAnalysis" and "G4ConvergenceTester" hits deques are 0057 /// memory-efficient version of the standard G4THitsMap. While maps are 0058 /// ideal for scoring at the G4Event-level, where sparsity w.r.t. indices 0059 /// is common; at the G4Run-level, these data structures require much 0060 /// less memory overhead. Due to a lack of 0061 /// G4ConvergenceTester::operator+=(G4ConvergenceTester), the static version 0062 /// of G4ConvergenceTester is the only valid way to use G4ConvergenceTester 0063 /// in a scoring container. This is not the case for G4StatAnalysis, which 0064 /// can be used in lieu of G4double. 0065 /// 0066 // 0067 // 0068 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 0069 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 0070 0071 #include "TSRun.hh" 0072 0073 #include "TSDetectorConstruction.hh" 0074 0075 #include "G4MultiFunctionalDetector.hh" 0076 #include "G4SDManager.hh" 0077 #include "G4VPrimitiveScorer.hh" 0078 0079 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 0080 0081 std::vector<G4TAtomicHitsMap<G4double>*> TSRun::fAtomicRunMaps; 0082 0083 std::map<G4String, TSRun::MutexHitsMap_t> TSRun::fMutexRunMaps; 0084 0085 std::vector<G4StatContainer<G4ConvergenceTester>*> TSRun::fConvMaps; 0086 0087 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 0088 0089 TSRun::TSRun(const G4String& mfd_name) : G4Run() 0090 { 0091 ConstructMFD(mfd_name); 0092 } 0093 0094 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 0095 0096 TSRun::~TSRun() 0097 { 0098 //--- Clear HitsMap for RUN 0099 for (unsigned i = 0; i < fRunMaps.size(); ++i) 0100 delete fRunMaps[i]; 0101 0102 if (!G4Threading::IsWorkerThread()) { 0103 for (unsigned i = 0; i < fAtomicRunMaps.size(); ++i) 0104 delete fAtomicRunMaps[i]; 0105 0106 for (auto& itr : fConvMaps) 0107 delete itr; 0108 0109 fAtomicRunMaps.clear(); 0110 fMutexRunMaps.clear(); 0111 fConvMaps.clear(); 0112 } 0113 } 0114 0115 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 0116 0117 // clear all data members. 0118 void TSRun::ConstructMFD(const G4String& mfdName) 0119 { 0120 G4SDManager* SDman = G4SDManager::GetSDMpointer(); 0121 //================================================= 0122 // Initalize RunMaps for accumulation. 0123 // Get CollectionIDs for HitCollections. 0124 //================================================= 0125 G4MultiFunctionalDetector* mfd = 0126 (G4MultiFunctionalDetector*)(SDman->FindSensitiveDetector(mfdName)); 0127 // 0128 if (mfd) { 0129 //--- Loop over the registered primitive scorers. 0130 for (G4int icol = 0; icol < mfd->GetNumberOfPrimitives(); icol++) { 0131 // Get Primitive Scorer object. 0132 G4VPrimitiveScorer* scorer = mfd->GetPrimitive(icol); 0133 // collection name and collectionID for HitsCollection, 0134 // where type of HitsCollection is G4THitsMap in case 0135 // of primitive scorer. 0136 // The collection name is given by <MFD name>/<Primitive 0137 // Scorer name>. 0138 G4String collectionName = scorer->GetName(); 0139 G4String fullCollectionName = mfdName + "/" + collectionName; 0140 G4int collectionID = SDman->GetCollectionID(fullCollectionName); 0141 // 0142 if (collectionID >= 0) { 0143 G4cout << "++ " << fullCollectionName << " id " << collectionID << G4endl; 0144 // Store obtained HitsCollection information into data members. 0145 // And, creates new G4THitsMap for accumulating quantities during RUN. 0146 fCollNames.push_back(fullCollectionName); 0147 fCollIDs.push_back(collectionID); 0148 fRunMaps.push_back(new G4THitsMap<G4double>(mfdName, collectionName)); 0149 fStatMaps.push_back(new G4StatContainer<G4StatAnalysis>( 0150 mfdName, collectionName, TSDetectorConstruction::Instance()->GetTotalTargets())); 0151 if (!G4Threading::IsWorkerThread()) { 0152 fAtomicRunMaps.push_back(new G4TAtomicHitsMap<G4double>(mfdName, collectionName)); 0153 fMutexRunMaps[fCollNames[collectionID]].clear(); 0154 fConvMaps.push_back(new G4StatContainer<G4ConvergenceTester>( 0155 mfdName, collectionName, TSDetectorConstruction::Instance()->GetTotalTargets())); 0156 } 0157 } 0158 else { 0159 G4cout << "** collection " << fullCollectionName << " not found. " << G4endl; 0160 } 0161 } 0162 } 0163 } 0164 0165 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 0166 // 0167 // RecordEvent is called at end of event. 0168 // For scoring purpose, the resultant quantity in a event, 0169 // is accumulated during a TSRun. 0170 void TSRun::RecordEvent(const G4Event* aEvent) 0171 { 0172 G4Run::RecordEvent(aEvent); 0173 0174 //============================= 0175 // HitsCollection of This Event 0176 //============================ 0177 G4HCofThisEvent* HCE = aEvent->GetHCofThisEvent(); 0178 if (!HCE) return; 0179 0180 for (unsigned i = 0; i < fCollIDs.size(); ++i) { 0181 G4int fCollID = fCollIDs.at(i); 0182 //======================================================= 0183 // Sum up HitsMap of this Event into HitsMap of this RUN 0184 //======================================================= 0185 G4THitsMap<G4double>* EvtMap = 0; 0186 if (fCollID >= 0) // Collection is attached to HCE 0187 EvtMap = static_cast<G4THitsMap<G4double>*>(HCE->GetHC(fCollID)); 0188 else 0189 G4cout << " Error EvtMap Not Found " << G4endl; 0190 0191 if (EvtMap) { 0192 //=== Sum up HitsMap of this event to HitsMap of RUN.=== 0193 { 0194 *fRunMaps[fCollID] += *EvtMap; 0195 } 0196 //=== Sum up HitsMap of this event to StatMap of RUN.=== 0197 { 0198 // G4StatAnalysis map 0199 *fStatMaps[fCollID] += *EvtMap; 0200 } 0201 //=== Sum up HitsMap of this event to atomic HitsMap of RUN.=== 0202 { 0203 *fAtomicRunMaps[fCollID] += *EvtMap; 0204 } 0205 //=== Sum up HitsMap of this event to MutexMap of RUN.=== 0206 { 0207 // mutex run map 0208 static G4Mutex mtx = G4MUTEX_INITIALIZER; 0209 G4AutoLock lock(&mtx); 0210 for (const auto& itr : *EvtMap) 0211 fMutexRunMaps[fCollNames[fCollID]][itr.first] += *itr.second; 0212 } 0213 //=== Sum up HitsMap of this event to MutexMap of RUN.=== 0214 { 0215 // G4ConvergenceTester run map 0216 static G4Mutex mtx = G4MUTEX_INITIALIZER; 0217 G4AutoLock lock(&mtx); 0218 *fConvMaps[fCollID] += *EvtMap; 0219 } 0220 } 0221 } 0222 } 0223 0224 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 0225 0226 // Merge hits map from threads 0227 void TSRun::Merge(const G4Run* aTSRun) 0228 { 0229 const TSRun* localTSRun = static_cast<const TSRun*>(aTSRun); 0230 0231 for (unsigned i = 0; i < fRunMaps.size(); ++i) { 0232 *fRunMaps[i] += *localTSRun->fRunMaps[i]; 0233 *fStatMaps[i] += *localTSRun->fStatMaps[i]; 0234 } 0235 0236 G4Run::Merge(aTSRun); 0237 } 0238 0239 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 0240 0241 // Access HitsMap. 0242 // by full description of collection name, that is 0243 // <MultiFunctional Detector Name>/<Primitive Scorer Name> 0244 G4THitsMap<G4double>* TSRun::GetHitsMap(const G4String& collName) const 0245 { 0246 for (unsigned i = 0; i < fCollNames.size(); ++i) { 0247 if (collName == fCollNames[i]) return fRunMaps[i]; 0248 } 0249 0250 G4Exception("TSRun", collName.c_str(), JustWarning, 0251 "GetHitsMap failed to locate the requested HitsMap"); 0252 return nullptr; 0253 } 0254 0255 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 0256 0257 // Access AtomicsHitsMap. 0258 // by full description of collection name, that is 0259 // <MultiFunctional Detector Name>/<Primitive Scorer Name> 0260 G4TAtomicHitsMap<G4double>* TSRun::GetAtomicHitsMap(const G4String& collName) const 0261 { 0262 for (unsigned i = 0; i < fCollNames.size(); ++i) { 0263 if (collName == fCollNames[i]) return fAtomicRunMaps[i]; 0264 } 0265 0266 G4Exception("TSRun", collName.c_str(), JustWarning, 0267 "GetHitsMap failed to locate the requested AtomicHitsMap"); 0268 return nullptr; 0269 } 0270 0271 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 0272 0273 // Access AtomicsHitsMap. 0274 // by full description of collection name, that is 0275 // <MultiFunctional Detector Name>/<Primitive Scorer Name> 0276 TSRun::MutexHitsMap_t* TSRun::GetMutexHitsMap(const G4String& collName) const 0277 { 0278 if (fMutexRunMaps.find(collName) != fMutexRunMaps.end()) return &fMutexRunMaps[collName]; 0279 0280 G4Exception("TSRun", collName.c_str(), JustWarning, 0281 "GetHitsMap failed to locate the requested MutexHitsMap"); 0282 return nullptr; 0283 } 0284 0285 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 0286 0287 // Access StatMap. 0288 // by full description of collection name, that is 0289 // <MultiFunctional Detector Name>/<Primitive Scorer Name> 0290 G4StatContainer<G4StatAnalysis>* TSRun::GetStatMap(const G4String& collName) const 0291 { 0292 for (unsigned i = 0; i < fCollNames.size(); ++i) { 0293 if (collName == fCollNames[i]) return fStatMaps[i]; 0294 } 0295 0296 G4Exception("TSRun", collName.c_str(), JustWarning, 0297 "GetStatMap failed to locate the requested StatMap"); 0298 return nullptr; 0299 } 0300 0301 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 0302 0303 G4StatContainer<G4ConvergenceTester>* TSRun::GetConvMap(const G4String& collName) const 0304 { 0305 for (unsigned i = 0; i < fCollNames.size(); ++i) { 0306 if (collName == fCollNames[i]) return fConvMaps[i]; 0307 } 0308 0309 G4Exception("TSRun", collName.c_str(), JustWarning, 0310 "GetHitsMap failed to locate the requested AtomicHitsMap"); 0311 return nullptr; 0312 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |