Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 27 // Author: Ivana Hrivnacova, IJCLab IN2P3/CNRS 28 29 #include "G4AccumulableManager.hh" 30 #include "G4ThreadLocalSingleton.hh" 31 #include "G4Threading.hh" 32 #include "G4AutoLock.hh" 33 34 // mutex in a file scope 35 36 namespace { 37 //Mutex to lock master manager when merging 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 } 49 50 //____________________________________________ 51 G4AccumulableManager* G4AccumulableManager::In 52 { 53 static G4ThreadLocalSingleton<G4AccumulableM 54 return instance.Instance(); 55 } 56 57 //____________________________________________ 58 G4AccumulableManager::G4AccumulableManager() 59 { 60 if (!G4Threading::IsWorkerThread()) { 61 fgMasterInstance = this; 62 } 63 } 64 65 //____________________________________________ 66 G4AccumulableManager::~G4AccumulableManager() 67 { 68 // delete only accumulables create by the ma 69 for ( auto it : fAccumulablesToDelete ) { 70 delete it; 71 } 72 } 73 74 // 75 // private methods 76 // 77 78 //____________________________________________ 79 G4String G4AccumulableManager::GenerateName() 80 { 81 G4String name = kBaseName; 82 std::ostringstream os; 83 os << fVector.size(); 84 name.append("_"); 85 name.append(os.str()); 86 return name; 87 } 88 89 //____________________________________________ 90 G4bool G4AccumulableManager::CheckName( 91 const G4String& name, const G4String& where) 92 { 93 if (fMap.find(name) == fMap.end()) { 94 return true; 95 } 96 97 G4ExceptionDescription description; 98 description << "Name " << name << " is alrea 99 description << "Parameter will be not create 100 G4String method("G4AccumulableManager::"); 101 method.append(where); 102 G4Exception(method, "Analysis_W001", JustWar 103 return false; 104 } 105 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 // 123 // public methods 124 // 125 126 //____________________________________________ 127 G4bool G4AccumulableManager::Register(G4VAccum 128 { 129 auto name = accumulable->GetName(); 130 131 if (G4Accumulables::VerboseLevel > 1 ) { 132 G4cout << "Going to register accumulable \ 133 } 134 135 // do not accept name if it is already used 136 if (!CheckName(name, "RegisterAccumulable")) 137 return false; 138 } 139 140 // generate name if empty 141 if (name.length() == 0u) { 142 name = GenerateName(); 143 accumulable->SetName(name); 144 } 145 146 // set Id 147 accumulable->SetId((G4int)fVector.size()); 148 149 fMap[name] = accumulable; 150 fVector.push_back(accumulable); 151 152 if (G4Accumulables::VerboseLevel > 0 ) { 153 G4cout << "Accumulable registered as \"" < 154 } 155 156 return true; 157 } 158 159 // Deprecated functions with long name 160 //____________________________________________ 161 G4bool G4AccumulableManager::RegisterAccumulab 162 { 163 return Register(accumulable); 164 } 165 166 //____________________________________________ 167 G4VAccumulable* 168 G4AccumulableManager::GetAccumulable(const G4S 169 { 170 // get G4VParammeter from the map 171 auto it = fMap.find(name); 172 if ( it == fMap.end() ) { 173 if ( warn) { 174 G4ExceptionDescription description; 175 description << "Accumulable " << name << 176 G4Exception("G4AccumulableManager::GetAc 177 "Analysis_W001", JustWarning 178 } 179 return nullptr; 180 } 181 182 return it->second; 183 } 184 185 //____________________________________________ 186 G4VAccumulable* 187 G4AccumulableManager::GetAccumulable(G4int id, 188 { 189 // get G4VParammeter from the vector 190 if ( id < 0 || id >= G4int(fVector.size()) ) 191 if ( warn) { 192 G4ExceptionDescription description; 193 description << "Accumulable " << id << " 194 G4Exception("G4AccumulableManager::GetAc 195 "Analysis_W001", JustWarning 196 } 197 return nullptr; 198 } 199 200 return fVector[id]; 201 } 202 203 //____________________________________________ 204 void G4AccumulableManager::Merge() 205 { 206 // Do nothing if there are no accumulables 207 // or if master thread 208 if ((fVector.size() == 0u) || (!G4Threading: 209 return; 210 } 211 212 // The manager on mastter must exist 213 if (fgMasterInstance == nullptr) { 214 G4ExceptionDescription description; 215 description 216 << "No master G4AccumulableManager insta 217 << "Accumulables will not be merged."; 218 G4Exception("G4AccumulableManager::Merge 219 "Analysis_W001", JustWarning, 220 return; 221 } 222 223 // The worker manager just merges its accumu 224 // This operation needs a lock 225 // G4cout << "Go to merge accumulables" << G 226 G4AutoLock lock(&mergeMutex); 227 228 // the other manager has the vector with the 229 auto it = fVector.begin(); 230 for ( auto itMaster : fgMasterInstance->fVec 231 // G4VAccumulable* masterAccumulable = itM 232 // G4VAccumulable* accumulable = *(it++); 233 // masterAccumulable->Merge(*(accumulable) 234 itMaster->Merge(*(*(it++))); 235 } 236 lock.unlock(); 237 } 238 239 //____________________________________________ 240 void G4AccumulableManager::Reset() 241 { 242 // Reset all accummulables 243 244 for ( auto it : fVector ) { 245 it->Reset(); 246 } 247 } 248 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 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