Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // >> 26 // $Id: G4AccumulableManager.cc 91116 2015-06-20 12:33:45Z ihrivnac $ 26 27 27 // Author: Ivana Hrivnacova, IJCLab IN2P3/CNRS << 28 // Author: Ivana Hrivnacova, 18/06/2013 (ivana@ipno.in2p3.fr) 28 29 29 #include "G4AccumulableManager.hh" 30 #include "G4AccumulableManager.hh" 30 #include "G4ThreadLocalSingleton.hh" << 31 #include "G4Threading.hh" 31 #include "G4Threading.hh" 32 #include "G4AutoLock.hh" 32 #include "G4AutoLock.hh" 33 33 34 // mutex in a file scope 34 // mutex in a file scope 35 35 36 namespace { 36 namespace { 37 //Mutex to lock master manager when merging 37 //Mutex to lock master manager when merging accumulables 38 G4Mutex mergeMutex = G4MUTEX_INITIALIZER; 38 G4Mutex mergeMutex = G4MUTEX_INITIALIZER; 39 << 40 void RangeException(const G4String& where, c << 41 { << 42 G4ExceptionDescription description; << 43 description << "Invalid range " << message << 44 G4String method("G4AccumulableManager::"); << 45 method.append(where); << 46 G4Exception(where, "Analysis_W001", JustWa << 47 } << 48 } 39 } 49 40 >> 41 G4AccumulableManager* G4AccumulableManager::fgMasterInstance = nullptr; >> 42 G4ThreadLocal G4AccumulableManager* G4AccumulableManager::fgInstance = nullptr; >> 43 50 //____________________________________________ 44 //_____________________________________________________________________________ 51 G4AccumulableManager* G4AccumulableManager::In 45 G4AccumulableManager* G4AccumulableManager::Instance() 52 { 46 { 53 static G4ThreadLocalSingleton<G4AccumulableM << 47 if ( fgInstance == nullptr ) { 54 return instance.Instance(); << 48 G4bool isMaster = ! G4Threading::IsWorkerThread(); 55 } << 49 fgInstance = new G4AccumulableManager(isMaster); >> 50 } >> 51 >> 52 return fgInstance; >> 53 } 56 54 57 //____________________________________________ 55 //_____________________________________________________________________________ 58 G4AccumulableManager::G4AccumulableManager() << 56 G4AccumulableManager::G4AccumulableManager(G4bool isMaster) >> 57 : fVector(), >> 58 fMap() 59 { 59 { 60 if (!G4Threading::IsWorkerThread()) { << 60 if ( ( isMaster && fgMasterInstance ) || ( fgInstance ) ) { 61 fgMasterInstance = this; << 61 G4ExceptionDescription description; >> 62 description >> 63 << " " >> 64 << "G4AccumulableAnalysisManager already exists." >> 65 << "Cannot create another instance."; >> 66 G4Exception("G4AccumulableAnalysisManager::G4AccumulableAnalysisManager()", >> 67 "Analysis_F001", FatalException, description); 62 } 68 } >> 69 if ( isMaster ) fgMasterInstance = this; >> 70 fgInstance = this; 63 } 71 } 64 72 65 //____________________________________________ 73 //_____________________________________________________________________________ 66 G4AccumulableManager::~G4AccumulableManager() 74 G4AccumulableManager::~G4AccumulableManager() 67 { 75 { 68 // delete only accumulables create by the ma 76 // delete only accumulables create by the mager itself 69 for ( auto it : fAccumulablesToDelete ) { 77 for ( auto it : fAccumulablesToDelete ) { 70 delete it; 78 delete it; 71 } 79 } 72 } 80 } 73 81 74 // 82 // 75 // private methods 83 // private methods 76 // 84 // 77 85 78 //____________________________________________ 86 //_____________________________________________________________________________ 79 G4String G4AccumulableManager::GenerateName() 87 G4String G4AccumulableManager::GenerateName() const 80 { 88 { 81 G4String name = kBaseName; 89 G4String name = kBaseName; 82 std::ostringstream os; 90 std::ostringstream os; 83 os << fVector.size(); 91 os << fVector.size(); 84 name.append("_"); 92 name.append("_"); 85 name.append(os.str()); 93 name.append(os.str()); 86 return name; 94 return name; 87 } 95 } 88 96 89 //____________________________________________ 97 //_____________________________________________________________________________ 90 G4bool G4AccumulableManager::CheckName( << 98 G4bool G4AccumulableManager::CheckName(const G4String& name, const G4String& where) const 91 const G4String& name, const G4String& where) << 92 { 99 { 93 if (fMap.find(name) == fMap.end()) { << 100 if ( fMap.find(name) == fMap.end() ) return true; 94 return true; << 101 95 } << 96 << 97 G4ExceptionDescription description; 102 G4ExceptionDescription description; 98 description << "Name " << name << " is alrea << 103 description << " " << "Name " << name << " is already used." << G4endl; 99 description << "Parameter will be not create << 104 description << " " << "Paremeter will be not created/registered."; 100 G4String method("G4AccumulableManager::"); 105 G4String method("G4AccumulableManager::"); 101 method.append(where); 106 method.append(where); 102 G4Exception(method, "Analysis_W001", JustWar << 107 G4Exception(method, "Analysis_W002", JustWarning, description); 103 return false; 108 return false; 104 } 109 } 105 110 106 //____________________________________________ << 107 G4bool G4AccumulableManager::CheckType( << 108 G4VAccumulable* accumulable, G4AccType type, << 109 { << 110 if (accumulable->GetType() != type) { << 111 if (warn) { << 112 G4ExceptionDescription description; << 113 description << " " << accumulable-> << 114 G4Exception("G4AccumulableManager::Check << 115 "Analysis_W001", JustWarning << 116 } << 117 return false; << 118 } << 119 return true; << 120 } << 121 << 122 // 111 // 123 // public methods 112 // public methods 124 // 113 // 125 114 126 //____________________________________________ 115 //_____________________________________________________________________________ 127 G4bool G4AccumulableManager::Register(G4VAccum << 116 G4bool G4AccumulableManager::RegisterAccumulable(G4VAccumulable* accumulable) 128 { 117 { 129 auto name = accumulable->GetName(); 118 auto name = accumulable->GetName(); 130 << 119 131 if (G4Accumulables::VerboseLevel > 1 ) { << 132 G4cout << "Going to register accumulable \ << 133 } << 134 << 135 // do not accept name if it is already used 120 // do not accept name if it is already used 136 if (!CheckName(name, "RegisterAccumulable")) << 121 if ( ! CheckName(name, "RegisterAccumulable") ) return false; 137 return false; << 138 } << 139 122 140 // generate name if empty 123 // generate name if empty 141 if (name.length() == 0u) { << 124 if ( ! name.length() ) { 142 name = GenerateName(); 125 name = GenerateName(); 143 accumulable->SetName(name); << 126 accumulable->fName = name; 144 } 127 } 145 128 146 // set Id << 147 accumulable->SetId((G4int)fVector.size()); << 148 << 149 fMap[name] = accumulable; 129 fMap[name] = accumulable; 150 fVector.push_back(accumulable); 130 fVector.push_back(accumulable); 151 << 152 if (G4Accumulables::VerboseLevel > 0 ) { << 153 G4cout << "Accumulable registered as \"" < << 154 } << 155 << 156 return true; 131 return true; 157 } 132 } 158 133 159 // Deprecated functions with long name << 160 //____________________________________________ << 161 G4bool G4AccumulableManager::RegisterAccumulab << 162 { << 163 return Register(accumulable); << 164 } << 165 << 166 //____________________________________________ 134 //_____________________________________________________________________________ 167 G4VAccumulable* << 135 G4VAccumulable* 168 G4AccumulableManager::GetAccumulable(const G4S 136 G4AccumulableManager::GetAccumulable(const G4String& name, G4bool warn) const 169 { 137 { 170 // get G4VParammeter from the map 138 // get G4VParammeter from the map 171 auto it = fMap.find(name); 139 auto it = fMap.find(name); 172 if ( it == fMap.end() ) { 140 if ( it == fMap.end() ) { 173 if ( warn) { 141 if ( warn) { 174 G4ExceptionDescription description; 142 G4ExceptionDescription description; 175 description << "Accumulable " << name << << 143 description << " " << "accumulable " << name << " does not exist."; 176 G4Exception("G4AccumulableManager::GetAc << 144 G4Exception("G4AccumulableManager::GetAccumulable", 177 "Analysis_W001", JustWarning << 145 "Analysis_W011", JustWarning, description); 178 } 146 } 179 return nullptr; 147 return nullptr; 180 } 148 } 181 149 182 return it->second; 150 return it->second; 183 } 151 } 184 152 185 //____________________________________________ 153 //_____________________________________________________________________________ 186 G4VAccumulable* << 154 G4VAccumulable* 187 G4AccumulableManager::GetAccumulable(G4int id, 155 G4AccumulableManager::GetAccumulable(G4int id, G4bool warn) const 188 { 156 { 189 // get G4VParammeter from the vector 157 // get G4VParammeter from the vector 190 if ( id < 0 || id >= G4int(fVector.size()) ) 158 if ( id < 0 || id >= G4int(fVector.size()) ) { 191 if ( warn) { 159 if ( warn) { 192 G4ExceptionDescription description; 160 G4ExceptionDescription description; 193 description << "Accumulable " << id << " << 161 description << " " << "accumulable " << id << " does not exist."; 194 G4Exception("G4AccumulableManager::GetAc << 162 G4Exception("G4AccumulableManager::GetAccumulable", 195 "Analysis_W001", JustWarning << 163 "Analysis_W011", JustWarning, description); 196 } 164 } 197 return nullptr; 165 return nullptr; 198 } 166 } 199 167 200 return fVector[id]; 168 return fVector[id]; 201 } 169 } 202 170 203 //____________________________________________ 171 //_____________________________________________________________________________ 204 void G4AccumulableManager::Merge() << 172 void G4AccumulableManager::Merge() 205 { 173 { 206 // Do nothing if there are no accumulables 174 // Do nothing if there are no accumulables registered 207 // or if master thread 175 // or if master thread 208 if ((fVector.size() == 0u) || (!G4Threading: << 176 if ( (! fVector.size()) || (! G4Threading::IsWorkerThread()) ) return; 209 return; << 210 } << 211 177 212 // The manager on mastter must exist 178 // The manager on mastter must exist 213 if (fgMasterInstance == nullptr) { << 179 if ( ! fgMasterInstance ) { 214 G4ExceptionDescription description; 180 G4ExceptionDescription description; 215 description << 181 description 216 << "No master G4AccumulableManager insta << 182 << " " << "No master G4AccumulableManager instance exists." 217 << "Accumulables will not be merged."; << 183 << G4endl >> 184 << " " << "Accumulables will not be merged."; 218 G4Exception("G4AccumulableManager::Merge 185 G4Exception("G4AccumulableManager::Merge()", 219 "Analysis_W001", JustWarning, << 186 "Analysis_W031", JustWarning, description); 220 return; 187 return; 221 } 188 } 222 189 223 // The worker manager just merges its accumu 190 // The worker manager just merges its accumulables to the master 224 // This operation needs a lock 191 // This operation needs a lock 225 // G4cout << "Go to merge accumulables" << G << 192 // G4cout << "Go to merge accumulables" << G4endl; 226 G4AutoLock lock(&mergeMutex); 193 G4AutoLock lock(&mergeMutex); 227 194 228 // the other manager has the vector with the 195 // the other manager has the vector with the "same" accumulables 229 auto it = fVector.begin(); 196 auto it = fVector.begin(); 230 for ( auto itMaster : fgMasterInstance->fVec 197 for ( auto itMaster : fgMasterInstance->fVector ) { 231 // G4VAccumulable* masterAccumulable = itM 198 // G4VAccumulable* masterAccumulable = itMaster; 232 // G4VAccumulable* accumulable = *(it++); 199 // G4VAccumulable* accumulable = *(it++); 233 // masterAccumulable->Merge(*(accumulable) 200 // masterAccumulable->Merge(*(accumulable)); 234 itMaster->Merge(*(*(it++))); 201 itMaster->Merge(*(*(it++))); 235 } << 202 } 236 lock.unlock(); 203 lock.unlock(); 237 } 204 } 238 205 239 //____________________________________________ 206 //_____________________________________________________________________________ 240 void G4AccumulableManager::Reset() 207 void G4AccumulableManager::Reset() 241 { 208 { 242 // Reset all accummulables << 209 // Reset histograms and profiles 243 << 210 244 for ( auto it : fVector ) { 211 for ( auto it : fVector ) { 245 it->Reset(); 212 it->Reset(); 246 } << 213 } 247 } << 214 } 248 << 215 249 //____________________________________________ << 250 void G4AccumulableManager::Print(G4PrintOption << 251 { << 252 for ( auto it : fVector ) { << 253 it->Print(options); << 254 } << 255 } << 256 216 257 //____________________________________________ << 258 void G4AccumulableManager::Print( << 259 G4int startId, G4int count, G4PrintOptions o << 260 { << 261 // check if range is within limits << 262 if ( startId < 0 || startId >= G4int(fVector << 263 count <= 0 || startId + count > G4int(f << 264 RangeException("Print", << 265 std::to_string(startId) + ", " + std::to << 266 return; << 267 } << 268 << 269 for ( auto id = startId; id < startId + coun << 270 fVector[id]->Print(options); << 271 } << 272 } << 273 << 274 //____________________________________________ << 275 void G4AccumulableManager::Print( << 276 std::vector<G4VAccumulable*>::iterator start << 277 std::vector<G4VAccumulable*>::iterator endIt << 278 G4PrintOptions options) const << 279 { << 280 // check if range is within limits << 281 if ( startIt == fVector.end() || endIt == fV << 282 RangeException("Print", "[startIt, endIt]" << 283 return; << 284 } << 285 << 286 for ( auto it = startIt; it != endIt; ++it ) << 287 (*it)->Print(options); << 288 } << 289 } << 290 << 291 //____________________________________________ << 292 void G4AccumulableManager::Print( << 293 std::vector<G4VAccumulable*>::iterator start << 294 G4PrintOptions options) const << 295 { << 296 Print(startIt, startIt+count, options); << 297 } << 298 217