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: G4XmlAnalysisManager.cc 103532 2017-04-13 14:00:35Z gcosmo $ 26 27 27 // Author: Ivana Hrivnacova, 18/06/2013 (ivan 28 // Author: Ivana Hrivnacova, 18/06/2013 (ivana@ipno.in2p3.fr) 28 29 29 #include "G4XmlAnalysisManager.hh" 30 #include "G4XmlAnalysisManager.hh" 30 #include "G4XmlFileManager.hh" 31 #include "G4XmlFileManager.hh" 31 #include "G4XmlNtupleFileManager.hh" << 32 #include "G4XmlNtupleManager.hh" 32 #include "G4AnalysisManagerState.hh" 33 #include "G4AnalysisManagerState.hh" 33 #include "G4AnalysisUtilities.hh" << 34 #include "G4ThreadLocalSingleton.hh" << 35 #include "G4Threading.hh" 34 #include "G4Threading.hh" >> 35 #include "G4AutoLock.hh" 36 36 37 using namespace G4Analysis; << 37 // mutex in a file scope 38 using std::make_shared; << 38 >> 39 namespace { >> 40 //Mutex to lock master manager when merging H1 histograms >> 41 G4Mutex mergeH1Mutex = G4MUTEX_INITIALIZER; >> 42 //Mutex to lock master manager when merging H1 histograms >> 43 G4Mutex mergeH2Mutex = G4MUTEX_INITIALIZER; >> 44 //Mutex to lock master manager when merging H1 histograms >> 45 G4Mutex mergeH3Mutex = G4MUTEX_INITIALIZER; >> 46 //Mutex to lock master manager when merging P1 profiles >> 47 G4Mutex mergeP1Mutex = G4MUTEX_INITIALIZER; >> 48 //Mutex to lock master manager when merging P2 profiles >> 49 G4Mutex mergeP2Mutex = G4MUTEX_INITIALIZER; >> 50 } >> 51 >> 52 G4XmlAnalysisManager* G4XmlAnalysisManager::fgMasterInstance = nullptr; >> 53 G4ThreadLocal G4XmlAnalysisManager* G4XmlAnalysisManager::fgInstance = nullptr; 39 54 40 //____________________________________________ 55 //_____________________________________________________________________________ 41 G4XmlAnalysisManager* G4XmlAnalysisManager::In 56 G4XmlAnalysisManager* G4XmlAnalysisManager::Instance() 42 { 57 { 43 static G4ThreadLocalSingleton<G4XmlAnalysisM << 58 if ( fgInstance == nullptr ) { 44 fgIsInstance = true; << 59 G4bool isMaster = ! G4Threading::IsWorkerThread(); 45 return instance.Instance(); << 60 fgInstance = new G4XmlAnalysisManager(isMaster); >> 61 } >> 62 >> 63 return fgInstance; 46 } 64 } 47 65 48 //____________________________________________ 66 //_____________________________________________________________________________ 49 G4bool G4XmlAnalysisManager::IsInstance() 67 G4bool G4XmlAnalysisManager::IsInstance() 50 { 68 { 51 return fgIsInstance; << 69 return ( fgInstance != 0 ); >> 70 } >> 71 >> 72 //_____________________________________________________________________________ >> 73 G4XmlAnalysisManager::G4XmlAnalysisManager(G4bool isMaster) >> 74 : G4ToolsAnalysisManager("Xml", isMaster), >> 75 fNtupleManager(nullptr), >> 76 fFileManager(nullptr) >> 77 { >> 78 if ( ( isMaster && fgMasterInstance ) || ( fgInstance ) ) { >> 79 G4ExceptionDescription description; >> 80 description >> 81 << " " >> 82 << "G4XmlAnalysisManager already exists." >> 83 << "Cannot create another instance."; >> 84 G4Exception("G4XmlAnalysisManager::G4XmlAnalysisManager", >> 85 "Analysis_F001", FatalException, description); >> 86 } >> 87 if ( isMaster ) fgMasterInstance = this; >> 88 fgInstance = this; >> 89 >> 90 // Create managers >> 91 fNtupleManager = new G4XmlNtupleManager(fState); >> 92 fFileManager = std::make_shared<G4XmlFileManager>(fState); >> 93 fNtupleManager->SetFileManager(fFileManager); >> 94 // The managers will be deleted by the base class >> 95 >> 96 // Set managers to base class which takes then their ownership >> 97 SetNtupleManager(fNtupleManager); >> 98 SetFileManager(fFileManager); 52 } 99 } 53 100 54 //____________________________________________ 101 //_____________________________________________________________________________ 55 G4XmlAnalysisManager::G4XmlAnalysisManager() << 102 G4XmlAnalysisManager::~G4XmlAnalysisManager() 56 : G4ToolsAnalysisManager("Xml") << 103 { >> 104 if ( fState.GetIsMaster() ) fgMasterInstance = nullptr; >> 105 fgInstance = nullptr; >> 106 } >> 107 >> 108 // >> 109 // private methods >> 110 // >> 111 >> 112 //_____________________________________________________________________________ >> 113 G4bool G4XmlAnalysisManager::WriteH1() 57 { 114 { 58 // File Manager << 115 auto h1Vector = fH1Manager->GetH1Vector(); 59 auto fileManager = std::make_shared<G4XmlFil << 116 auto hnVector = fH1Manager->GetHnVector(); 60 SetFileManager(fileManager); << 61 117 62 // Ntuple file manager << 118 if ( ! h1Vector.size() ) return true; 63 fNtupleFileManager = std::make_shared<G4XmlN << 119 64 SetNtupleFileManager(fNtupleFileManager); << 120 auto result = true; 65 fNtupleFileManager->SetFileManager(std::move << 121 66 fNtupleFileManager->SetBookingManager(fNtupl << 122 if ( ! G4Threading::IsWorkerThread() ) { >> 123 auto directoryName = fFileManager->GetHistoDirectoryName(); >> 124 result = WriteT(h1Vector, hnVector, directoryName, "h1"); >> 125 } >> 126 else { >> 127 // The worker manager just adds its histograms to the master >> 128 // This operation needs a lock >> 129 G4AutoLock lH1(&mergeH1Mutex); >> 130 fgMasterInstance->fH1Manager->AddH1Vector(h1Vector); >> 131 lH1.unlock(); >> 132 } >> 133 >> 134 return result; >> 135 } >> 136 >> 137 //_____________________________________________________________________________ >> 138 G4bool G4XmlAnalysisManager::WriteH2() >> 139 { >> 140 auto h2Vector = fH2Manager->GetH2Vector(); >> 141 auto hnVector = fH2Manager->GetHnVector(); >> 142 >> 143 if ( ! h2Vector.size() ) return true; >> 144 >> 145 auto result = true; >> 146 >> 147 if ( ! G4Threading::IsWorkerThread() ) { >> 148 auto directoryName = fFileManager->GetHistoDirectoryName(); >> 149 result = WriteT(h2Vector, hnVector, directoryName, "h2"); >> 150 } >> 151 else { >> 152 // The worker manager just adds its histograms to the master >> 153 // This operation needs a lock >> 154 G4AutoLock lH2(&mergeH2Mutex); >> 155 fgMasterInstance->fH2Manager->AddH2Vector(h2Vector); >> 156 lH2.unlock(); >> 157 } >> 158 >> 159 return result; 67 } 160 } 68 161 69 //____________________________________________ 162 //_____________________________________________________________________________ 70 G4XmlAnalysisManager::~G4XmlAnalysisManager() << 163 G4bool G4XmlAnalysisManager::WriteH3() >> 164 { >> 165 auto h3Vector = fH3Manager->GetH3Vector(); >> 166 auto hnVector = fH3Manager->GetHnVector(); >> 167 >> 168 if ( ! h3Vector.size() ) return true; >> 169 >> 170 auto result = true; >> 171 >> 172 if ( ! G4Threading::IsWorkerThread() ) { >> 173 auto directoryName = fFileManager->GetHistoDirectoryName(); >> 174 result = WriteT(h3Vector, hnVector, directoryName, "h3"); >> 175 } >> 176 else { >> 177 // The worker manager just adds its histograms to the master >> 178 // This operation needs a lock >> 179 G4AutoLock lH3(&mergeH3Mutex); >> 180 fgMasterInstance->fH3Manager->AddH3Vector(h3Vector); >> 181 lH3.unlock(); >> 182 } >> 183 >> 184 return result; >> 185 } >> 186 >> 187 //_____________________________________________________________________________ >> 188 G4bool G4XmlAnalysisManager::WriteP1() >> 189 { >> 190 auto p1Vector = fP1Manager->GetP1Vector(); >> 191 auto hnVector = fP1Manager->GetHnVector(); >> 192 >> 193 if ( ! p1Vector.size() ) return true; >> 194 >> 195 auto result = true; >> 196 >> 197 if ( ! G4Threading::IsWorkerThread() ) { >> 198 auto directoryName = fFileManager->GetHistoDirectoryName(); >> 199 result = WriteT(p1Vector, hnVector, directoryName, "p1"); >> 200 } >> 201 else { >> 202 // The worker manager just adds its profiles to the master >> 203 // This operation needs a lock >> 204 G4AutoLock lP1(&mergeP1Mutex); >> 205 fgMasterInstance->fP1Manager->AddP1Vector(p1Vector); >> 206 lP1.unlock(); >> 207 } >> 208 >> 209 return result; >> 210 } >> 211 >> 212 //_____________________________________________________________________________ >> 213 G4bool G4XmlAnalysisManager::WriteP2() >> 214 { >> 215 auto p2Vector = fP2Manager->GetP2Vector(); >> 216 auto hnVector = fP2Manager->GetHnVector(); >> 217 >> 218 if ( ! p2Vector.size() ) return true; >> 219 >> 220 auto result = true; >> 221 >> 222 if ( ! G4Threading::IsWorkerThread() ) { >> 223 auto directoryName = fFileManager->GetHistoDirectoryName(); >> 224 result = WriteT(p2Vector, hnVector, directoryName, "p2"); >> 225 } >> 226 else { >> 227 // The worker manager just adds its profiles to the master >> 228 // This operation needs a lock >> 229 G4AutoLock lP2(&mergeP2Mutex); >> 230 fgMasterInstance->fP2Manager->AddP2Vector(p2Vector); >> 231 lP2.unlock(); >> 232 } >> 233 >> 234 return result; >> 235 } >> 236 >> 237 //_____________________________________________________________________________ >> 238 G4bool G4XmlAnalysisManager::WriteNtuple() >> 239 { >> 240 auto ntupleVector = fNtupleManager->GetNtupleDescriptionVector(); >> 241 >> 242 for ( auto ntuple : ntupleVector ) { >> 243 if ( ntuple->fNtuple ) ntuple->fNtuple->write_trailer(); >> 244 } >> 245 >> 246 return true; >> 247 } >> 248 >> 249 //_____________________________________________________________________________ >> 250 G4bool G4XmlAnalysisManager::CloseNtupleFiles() 71 { 251 { 72 fgIsInstance = false; << 252 auto ntupleDescriptionVector = fNtupleManager->GetNtupleDescriptionVector(); >> 253 >> 254 // Close ntuple files >> 255 for ( auto ntupleDescription : ntupleDescriptionVector) { >> 256 fFileManager->CloseNtupleFile((ntupleDescription)); >> 257 } >> 258 >> 259 return true; >> 260 } >> 261 >> 262 >> 263 //_____________________________________________________________________________ >> 264 G4bool G4XmlAnalysisManager::Reset() >> 265 { >> 266 // Reset histograms and ntuple >> 267 >> 268 auto finalResult = true; >> 269 >> 270 auto result = G4ToolsAnalysisManager::Reset(); >> 271 finalResult = finalResult && result; >> 272 >> 273 result = fNtupleManager->Reset(true); >> 274 finalResult = finalResult && result; >> 275 >> 276 return finalResult; >> 277 } >> 278 >> 279 // >> 280 // protected methods >> 281 // >> 282 >> 283 //_____________________________________________________________________________ >> 284 G4bool G4XmlAnalysisManager::OpenFileImpl(const G4String& fileName) >> 285 { >> 286 auto finalResult = true; >> 287 auto result = fFileManager->SetFileName(fileName); >> 288 finalResult = finalResult && result; >> 289 >> 290 #ifdef G4VERBOSE >> 291 auto name = fFileManager->GetFullFileName(); >> 292 if ( fState.GetVerboseL4() ) { >> 293 fState.GetVerboseL4()->Message("open", "analysis file", name); >> 294 } >> 295 #endif >> 296 >> 297 // Only lock file name in file manager >> 298 result = fFileManager->OpenFile(fileName); >> 299 finalResult = finalResult && result; >> 300 >> 301 // Create histograms file (on master) >> 302 if ( fState.GetIsMaster() ) { >> 303 result = fFileManager->CreateHnFile(); >> 304 finalResult = finalResult && result; >> 305 } >> 306 >> 307 // Create ntuples if they are booked >> 308 // (The files will be created with creating ntuples) >> 309 fNtupleManager->CreateNtuplesFromBooking(); >> 310 >> 311 #ifdef G4VERBOSE >> 312 if ( fState.GetVerboseL1() ) >> 313 fState.GetVerboseL1()->Message("open", "analysis file", name, finalResult); >> 314 #endif >> 315 >> 316 return finalResult; >> 317 } >> 318 >> 319 //_____________________________________________________________________________ >> 320 G4bool G4XmlAnalysisManager::WriteImpl() >> 321 { >> 322 auto finalResult = true; >> 323 >> 324 #ifdef G4VERBOSE >> 325 auto name = fFileManager->GetFullFileName(); >> 326 if ( fState.GetVerboseL4() ) >> 327 fState.GetVerboseL4()->Message("write", "files", name); >> 328 #endif >> 329 >> 330 // ntuples >> 331 WriteNtuple(); >> 332 >> 333 if ( ! fgMasterInstance && >> 334 ( ( ! fH1Manager->IsEmpty() ) || ( ! fH2Manager->IsEmpty() ) || >> 335 ( ! fH3Manager->IsEmpty() ) || ( ! fP1Manager->IsEmpty() ) || >> 336 ( ! fP2Manager->IsEmpty() ) ) ) { >> 337 >> 338 G4ExceptionDescription description; >> 339 description >> 340 << " " << "No master G4XmlAnalysisManager instance exists." >> 341 << G4endl >> 342 << " " << "Histogram data will not be merged."; >> 343 G4Exception("G4XmlAnalysisManager::Write()", >> 344 "Analysis_W031", JustWarning, description); >> 345 >> 346 // Create Hn file per thread >> 347 auto result = fFileManager->CreateHnFile(); >> 348 if ( ! result ) return false; >> 349 } >> 350 >> 351 // H1 >> 352 auto result = WriteH1(); >> 353 finalResult = finalResult && result; >> 354 >> 355 // H2 >> 356 result = WriteH2(); >> 357 finalResult = finalResult && result; >> 358 >> 359 // H3 >> 360 result = WriteH3(); >> 361 finalResult = finalResult && result; >> 362 >> 363 // P1 >> 364 result = WriteP1(); >> 365 finalResult = finalResult && result; >> 366 >> 367 // P2 >> 368 result = WriteP2(); >> 369 finalResult = finalResult && result; >> 370 >> 371 // Write ASCII if activated >> 372 if ( IsAscii() ) { >> 373 result = WriteAscii(fFileManager->GetFileName()); >> 374 finalResult = finalResult && result; >> 375 } >> 376 >> 377 #ifdef G4VERBOSE >> 378 if ( fState.GetVerboseL1() ) >> 379 fState.GetVerboseL1() >> 380 ->Message("write", "file", fFileManager->GetFullFileName(), finalResult); >> 381 #endif >> 382 >> 383 return finalResult; >> 384 } >> 385 >> 386 //_____________________________________________________________________________ >> 387 G4bool G4XmlAnalysisManager::CloseFileImpl() >> 388 { >> 389 auto finalResult = true; >> 390 >> 391 #ifdef G4VERBOSE >> 392 if ( fState.GetVerboseL4() ) >> 393 fState.GetVerboseL4()->Message("close", "files", ""); >> 394 #endif >> 395 >> 396 // Unlock file name only >> 397 auto result = fFileManager->CloseFile(); >> 398 finalResult = finalResult && result; >> 399 >> 400 // Close Hn file >> 401 result = fFileManager->CloseHnFile(); >> 402 finalResult = finalResult && result; >> 403 >> 404 // Close ntuple files >> 405 result = CloseNtupleFiles(); >> 406 finalResult = finalResult && result; >> 407 >> 408 // reset data >> 409 result = Reset(); >> 410 if ( ! result ) { >> 411 G4ExceptionDescription description; >> 412 description << " " << "Resetting data failed"; >> 413 G4Exception("G4XmlAnalysisManager::CloseFile()", >> 414 "Analysis_W021", JustWarning, description); >> 415 } >> 416 finalResult = finalResult && result; >> 417 >> 418 // delete files if empty >> 419 // (ntuple files are created only if an ntuple is created) >> 420 if ( fFileManager->GetHnFile().get() && >> 421 fH1Manager->IsEmpty() && fH2Manager->IsEmpty() && fH3Manager->IsEmpty() && >> 422 fP1Manager->IsEmpty() && fP2Manager->IsEmpty() ) { >> 423 result = ! std::remove(fFileManager->GetFullFileName()); >> 424 // std::remove returns 0 when success >> 425 if ( ! result ) { >> 426 G4ExceptionDescription description; >> 427 description << " " << "Removing file " >> 428 << fFileManager->GetFullFileName() << " failed"; >> 429 G4Exception("G4XmlAnalysisManager::CloseFile()", >> 430 "Analysis_W021", JustWarning, description); >> 431 } >> 432 finalResult = finalResult && result; >> 433 #ifdef G4VERBOSE >> 434 if ( fState.GetVerboseL1() ) >> 435 fState.GetVerboseL1() >> 436 ->Message("delete", "empty file", fFileManager->GetFullFileName()); >> 437 #endif >> 438 } >> 439 else { >> 440 #ifdef G4VERBOSE >> 441 if ( fState.GetVerboseL2() ) >> 442 fState.GetVerboseL2() >> 443 ->Message("close", "files", ""); >> 444 #endif >> 445 } >> 446 >> 447 return finalResult; 73 } 448 } 74 449