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 26 27 // Author: Ivana Hrivnacova, IJCLab IN2P3/CNRS << 27 // Author: Ivana Hrivnacova, 18/06/2013 (ivana@ipno.in2p3.fr) 28 28 29 #include "G4AccumulableManager.hh" 29 #include "G4AccumulableManager.hh" 30 #include "G4ThreadLocalSingleton.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 50 //____________________________________________ 41 //_____________________________________________________________________________ 51 G4AccumulableManager* G4AccumulableManager::In 42 G4AccumulableManager* G4AccumulableManager::Instance() 52 { 43 { 53 static G4ThreadLocalSingleton<G4AccumulableM 44 static G4ThreadLocalSingleton<G4AccumulableManager> instance; 54 return instance.Instance(); 45 return instance.Instance(); 55 } 46 } 56 47 57 //____________________________________________ 48 //_____________________________________________________________________________ 58 G4AccumulableManager::G4AccumulableManager() 49 G4AccumulableManager::G4AccumulableManager() 59 { 50 { 60 if (!G4Threading::IsWorkerThread()) { << 51 if ( ! G4Threading::IsWorkerThread() ) fgMasterInstance = this; 61 fgMasterInstance = this; << 62 } << 63 } 52 } 64 53 65 //____________________________________________ 54 //_____________________________________________________________________________ 66 G4AccumulableManager::~G4AccumulableManager() 55 G4AccumulableManager::~G4AccumulableManager() 67 { 56 { 68 // delete only accumulables create by the ma 57 // delete only accumulables create by the mager itself 69 for ( auto it : fAccumulablesToDelete ) { 58 for ( auto it : fAccumulablesToDelete ) { 70 delete it; 59 delete it; 71 } 60 } 72 } 61 } 73 62 74 // 63 // 75 // private methods 64 // private methods 76 // 65 // 77 66 78 //____________________________________________ 67 //_____________________________________________________________________________ 79 G4String G4AccumulableManager::GenerateName() 68 G4String G4AccumulableManager::GenerateName() const 80 { 69 { 81 G4String name = kBaseName; 70 G4String name = kBaseName; 82 std::ostringstream os; 71 std::ostringstream os; 83 os << fVector.size(); 72 os << fVector.size(); 84 name.append("_"); 73 name.append("_"); 85 name.append(os.str()); 74 name.append(os.str()); 86 return name; 75 return name; 87 } 76 } 88 77 89 //____________________________________________ 78 //_____________________________________________________________________________ 90 G4bool G4AccumulableManager::CheckName( << 79 G4bool G4AccumulableManager::CheckName(const G4String& name, const G4String& where) const 91 const G4String& name, const G4String& where) << 92 { 80 { 93 if (fMap.find(name) == fMap.end()) { << 81 if ( fMap.find(name) == fMap.end() ) return true; 94 return true; << 95 } << 96 82 97 G4ExceptionDescription description; 83 G4ExceptionDescription description; 98 description << "Name " << name << " is alrea 84 description << "Name " << name << " is already used." << G4endl; 99 description << "Parameter will be not create 85 description << "Parameter will be not created/registered."; 100 G4String method("G4AccumulableManager::"); 86 G4String method("G4AccumulableManager::"); 101 method.append(where); 87 method.append(where); 102 G4Exception(method, "Analysis_W001", JustWar 88 G4Exception(method, "Analysis_W001", JustWarning, description); 103 return false; 89 return false; 104 } 90 } 105 91 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 // 92 // 123 // public methods 93 // public methods 124 // 94 // 125 95 126 //____________________________________________ 96 //_____________________________________________________________________________ 127 G4bool G4AccumulableManager::Register(G4VAccum << 97 G4bool G4AccumulableManager::RegisterAccumulable(G4VAccumulable* accumulable) 128 { 98 { 129 auto name = accumulable->GetName(); 99 auto name = accumulable->GetName(); 130 100 131 if (G4Accumulables::VerboseLevel > 1 ) { << 132 G4cout << "Going to register accumulable \ << 133 } << 134 << 135 // do not accept name if it is already used 101 // do not accept name if it is already used 136 if (!CheckName(name, "RegisterAccumulable")) << 102 if ( ! CheckName(name, "RegisterAccumulable") ) return false; 137 return false; << 138 } << 139 103 140 // generate name if empty 104 // generate name if empty 141 if (name.length() == 0u) { << 105 if ( ! name.length() ) { 142 name = GenerateName(); 106 name = GenerateName(); 143 accumulable->SetName(name); << 107 accumulable->fName = name; 144 } 108 } 145 109 146 // set Id << 147 accumulable->SetId((G4int)fVector.size()); << 148 << 149 fMap[name] = accumulable; 110 fMap[name] = accumulable; 150 fVector.push_back(accumulable); 111 fVector.push_back(accumulable); 151 << 152 if (G4Accumulables::VerboseLevel > 0 ) { << 153 G4cout << "Accumulable registered as \"" < << 154 } << 155 << 156 return true; 112 return true; 157 } 113 } 158 114 159 // Deprecated functions with long name << 160 //____________________________________________ << 161 G4bool G4AccumulableManager::RegisterAccumulab << 162 { << 163 return Register(accumulable); << 164 } << 165 << 166 //____________________________________________ 115 //_____________________________________________________________________________ 167 G4VAccumulable* 116 G4VAccumulable* 168 G4AccumulableManager::GetAccumulable(const G4S 117 G4AccumulableManager::GetAccumulable(const G4String& name, G4bool warn) const 169 { 118 { 170 // get G4VParammeter from the map 119 // get G4VParammeter from the map 171 auto it = fMap.find(name); 120 auto it = fMap.find(name); 172 if ( it == fMap.end() ) { 121 if ( it == fMap.end() ) { 173 if ( warn) { 122 if ( warn) { 174 G4ExceptionDescription description; 123 G4ExceptionDescription description; 175 description << "Accumulable " << name << 124 description << "Accumulable " << name << " does not exist."; 176 G4Exception("G4AccumulableManager::GetAc 125 G4Exception("G4AccumulableManager::GetAccumulable", 177 "Analysis_W001", JustWarning 126 "Analysis_W001", JustWarning, description); 178 } 127 } 179 return nullptr; 128 return nullptr; 180 } 129 } 181 130 182 return it->second; 131 return it->second; 183 } 132 } 184 133 185 //____________________________________________ 134 //_____________________________________________________________________________ 186 G4VAccumulable* 135 G4VAccumulable* 187 G4AccumulableManager::GetAccumulable(G4int id, 136 G4AccumulableManager::GetAccumulable(G4int id, G4bool warn) const 188 { 137 { 189 // get G4VParammeter from the vector 138 // get G4VParammeter from the vector 190 if ( id < 0 || id >= G4int(fVector.size()) ) 139 if ( id < 0 || id >= G4int(fVector.size()) ) { 191 if ( warn) { 140 if ( warn) { 192 G4ExceptionDescription description; 141 G4ExceptionDescription description; 193 description << "Accumulable " << id << " 142 description << "Accumulable " << id << " does not exist."; 194 G4Exception("G4AccumulableManager::GetAc 143 G4Exception("G4AccumulableManager::GetAccumulable", 195 "Analysis_W001", JustWarning 144 "Analysis_W001", JustWarning, description); 196 } 145 } 197 return nullptr; 146 return nullptr; 198 } 147 } 199 148 200 return fVector[id]; 149 return fVector[id]; 201 } 150 } 202 151 203 //____________________________________________ 152 //_____________________________________________________________________________ 204 void G4AccumulableManager::Merge() 153 void G4AccumulableManager::Merge() 205 { 154 { 206 // Do nothing if there are no accumulables 155 // Do nothing if there are no accumulables registered 207 // or if master thread 156 // or if master thread 208 if ((fVector.size() == 0u) || (!G4Threading: << 157 if ( (! fVector.size()) || (! G4Threading::IsWorkerThread()) ) return; 209 return; << 210 } << 211 158 212 // The manager on mastter must exist 159 // The manager on mastter must exist 213 if (fgMasterInstance == nullptr) { << 160 if ( ! fgMasterInstance ) { 214 G4ExceptionDescription description; 161 G4ExceptionDescription description; 215 description 162 description 216 << "No master G4AccumulableManager insta 163 << "No master G4AccumulableManager instance exists." << G4endl 217 << "Accumulables will not be merged."; 164 << "Accumulables will not be merged."; 218 G4Exception("G4AccumulableManager::Merge 165 G4Exception("G4AccumulableManager::Merge()", 219 "Analysis_W001", JustWarning, 166 "Analysis_W001", JustWarning, description); 220 return; 167 return; 221 } 168 } 222 169 223 // The worker manager just merges its accumu 170 // The worker manager just merges its accumulables to the master 224 // This operation needs a lock 171 // This operation needs a lock 225 // G4cout << "Go to merge accumulables" << G 172 // G4cout << "Go to merge accumulables" << G4endl; 226 G4AutoLock lock(&mergeMutex); 173 G4AutoLock lock(&mergeMutex); 227 174 228 // the other manager has the vector with the 175 // the other manager has the vector with the "same" accumulables 229 auto it = fVector.begin(); 176 auto it = fVector.begin(); 230 for ( auto itMaster : fgMasterInstance->fVec 177 for ( auto itMaster : fgMasterInstance->fVector ) { 231 // G4VAccumulable* masterAccumulable = itM 178 // G4VAccumulable* masterAccumulable = itMaster; 232 // G4VAccumulable* accumulable = *(it++); 179 // G4VAccumulable* accumulable = *(it++); 233 // masterAccumulable->Merge(*(accumulable) 180 // masterAccumulable->Merge(*(accumulable)); 234 itMaster->Merge(*(*(it++))); 181 itMaster->Merge(*(*(it++))); 235 } 182 } 236 lock.unlock(); 183 lock.unlock(); 237 } 184 } 238 185 239 //____________________________________________ 186 //_____________________________________________________________________________ 240 void G4AccumulableManager::Reset() 187 void G4AccumulableManager::Reset() 241 { 188 { 242 // Reset all accummulables << 189 // Reset histograms and profiles 243 190 244 for ( auto it : fVector ) { 191 for ( auto it : fVector ) { 245 it->Reset(); 192 it->Reset(); 246 } 193 } 247 } 194 } 248 195 249 //____________________________________________ << 250 void G4AccumulableManager::Print(G4PrintOption << 251 { << 252 for ( auto it : fVector ) { << 253 it->Print(options); << 254 } << 255 } << 256 << 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 196 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 197