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