Back to home page

EIC code displayed by LXR

 
 

    


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 }