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