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: G4RootAnalysisManager.cc 105132 2017-07-14 07:21:54Z 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 "G4RootAnalysisManager.hh" 30 #include "G4RootAnalysisManager.hh" 30 #include "G4RootFileManager.hh" 31 #include "G4RootFileManager.hh" 31 #include "G4RootNtupleFileManager.hh" << 32 #include "G4RootNtupleManager.hh" >> 33 #include "G4RootMainNtupleManager.hh" >> 34 #include "G4RootPNtupleManager.hh" >> 35 #include "G4AnalysisVerbose.hh" 32 #include "G4AnalysisManagerState.hh" 36 #include "G4AnalysisManagerState.hh" 33 #include "G4AnalysisUtilities.hh" << 37 34 #include "G4ThreadLocalSingleton.hh" << 35 #include "G4Threading.hh" 38 #include "G4Threading.hh" >> 39 #include "G4AutoLock.hh" >> 40 >> 41 #include <iostream> >> 42 #include <cstdio> >> 43 >> 44 // mutex in a file scope 36 45 37 using namespace G4Analysis; << 46 namespace { >> 47 //Mutex to lock master manager when merging H1 histograms >> 48 G4Mutex mergeH1Mutex = G4MUTEX_INITIALIZER; >> 49 //Mutex to lock master manager when merging H1 histograms >> 50 G4Mutex mergeH2Mutex = G4MUTEX_INITIALIZER; >> 51 //Mutex to lock master manager when merging H1 histograms >> 52 G4Mutex mergeH3Mutex = G4MUTEX_INITIALIZER; >> 53 //Mutex to lock master manager when merging P1 profiles >> 54 G4Mutex mergeP1Mutex = G4MUTEX_INITIALIZER; >> 55 //Mutex to lock master manager when merging P2 profiles >> 56 G4Mutex mergeP2Mutex = G4MUTEX_INITIALIZER; >> 57 } >> 58 >> 59 G4RootAnalysisManager* G4RootAnalysisManager::fgMasterInstance = nullptr; >> 60 G4ThreadLocal G4RootAnalysisManager* G4RootAnalysisManager::fgInstance = nullptr; 38 61 39 //____________________________________________ 62 //_____________________________________________________________________________ 40 G4RootAnalysisManager* G4RootAnalysisManager:: 63 G4RootAnalysisManager* G4RootAnalysisManager::Instance() 41 { 64 { 42 static G4ThreadLocalSingleton<G4RootAnalysis << 65 if ( fgInstance == nullptr ) { 43 fgIsInstance = true; << 66 G4bool isMaster = ! G4Threading::IsWorkerThread(); 44 return instance.Instance(); << 67 fgInstance = new G4RootAnalysisManager(isMaster); 45 } << 68 } >> 69 >> 70 return fgInstance; >> 71 } 46 72 47 //____________________________________________ 73 //_____________________________________________________________________________ 48 G4bool G4RootAnalysisManager::IsInstance() 74 G4bool G4RootAnalysisManager::IsInstance() 49 { 75 { 50 return fgIsInstance; << 76 return ( fgInstance != 0 ); 51 } << 77 } 52 78 53 //____________________________________________ 79 //_____________________________________________________________________________ 54 G4RootAnalysisManager::G4RootAnalysisManager() << 80 G4RootAnalysisManager::G4RootAnalysisManager(G4bool isMaster) 55 : G4ToolsAnalysisManager("Root") << 81 : G4ToolsAnalysisManager("Root", isMaster), >> 82 fNofNtupleFiles(0), >> 83 fNtupleMergeMode(G4NtupleMergeMode::kNone), >> 84 fNtupleManager(nullptr), >> 85 fSlaveNtupleManager(nullptr), >> 86 fFileManager(nullptr) 56 { 87 { >> 88 if ( ( isMaster && fgMasterInstance ) || ( fgInstance ) ) { >> 89 G4ExceptionDescription description; >> 90 description >> 91 << " " >> 92 << "G4RootAnalysisManager already exists." >> 93 << "Cannot create another instance."; >> 94 G4Exception("G4RootAnalysisManager::G4RootAnalysisManager()", >> 95 "Analysis_F001", FatalException, description); >> 96 } >> 97 if ( isMaster ) fgMasterInstance = this; >> 98 fgInstance = this; >> 99 57 // File manager 100 // File manager 58 fFileManager = std::make_shared<G4RootFileMa 101 fFileManager = std::make_shared<G4RootFileManager>(fState); 59 SetFileManager(fFileManager); 102 SetFileManager(fFileManager); >> 103 fFileManager->SetBasketSize(fgkDefaultBasketSize); 60 104 61 // Ntuple file manager << 105 // Do not merge ntuples by default 62 fNtupleFileManager = std::make_shared<G4Root << 106 // Merging may require user code migration as analysis manager 63 SetNtupleFileManager(fNtupleFileManager); << 107 // must be created both on master and workers. 64 fNtupleFileManager->SetFileManager(fFileMana << 108 auto mergeNtuples = false; 65 fNtupleFileManager->SetBookingManager(fNtupl << 109 SetNtupleMergingMode(mergeNtuples, fNofNtupleFiles); 66 } << 67 110 >> 111 // Create ntuple managers >> 112 CreateNtupleManagers(); >> 113 } >> 114 68 //____________________________________________ 115 //_____________________________________________________________________________ 69 G4RootAnalysisManager::~G4RootAnalysisManager( 116 G4RootAnalysisManager::~G4RootAnalysisManager() 70 { 117 { 71 fgIsInstance = false; << 118 if ( fState.GetIsMaster() ) fgMasterInstance = nullptr; >> 119 fgInstance = nullptr; 72 } 120 } 73 121 74 // << 122 // 75 // public methods << 123 // private methods 76 // 124 // 77 125 78 //____________________________________________ 126 //_____________________________________________________________________________ 79 void G4RootAnalysisManager::SetNtupleMerging(G << 127 void G4RootAnalysisManager::SetNtupleMergingMode(G4bool mergeNtuples, 80 G << 128 G4int nofNtupleFiles) >> 129 81 { 130 { 82 fNtupleFileManager->SetNtupleMerging(mergeNt << 131 #ifdef G4VERBOSE >> 132 if ( fState.GetVerboseL4() ) >> 133 fState.GetVerboseL4() >> 134 ->Message("set", "ntuple merging mode", ""); >> 135 #endif >> 136 >> 137 auto canMerge = true; >> 138 >> 139 // Illegal situations >> 140 if ( mergeNtuples && ( ! G4Threading::IsMultithreadedApplication() ) ) { >> 141 if ( nofNtupleFiles > 0 ) { >> 142 G4ExceptionDescription description; >> 143 description >> 144 << " " << "Merging ntuples is not applicable in sequential application." >> 145 << G4endl >> 146 << " " << "Setting was ignored."; >> 147 G4Exception("G4RootAnalysisManager::SetNtupleMergingMode()", >> 148 "Analysis_W013", JustWarning, description); >> 149 } >> 150 canMerge = false; >> 151 } >> 152 >> 153 // Illegal situations >> 154 if ( mergeNtuples && G4Threading::IsMultithreadedApplication() && >> 155 ( ! fgMasterInstance ) ) { >> 156 G4ExceptionDescription description; >> 157 description >> 158 << " " << "Merging ntuples requires G4AnalysisManager instance on master." >> 159 << G4endl >> 160 << " " << "Setting was ignored."; >> 161 G4Exception("G4RootAnalysisManager::SetNtupleMergingMode()", >> 162 "Analysis_W013", JustWarning, description); >> 163 canMerge = false; >> 164 } >> 165 >> 166 G4String mergingMode; >> 167 if ( ( ! mergeNtuples ) || ( ! canMerge ) ) { >> 168 fNtupleMergeMode = G4NtupleMergeMode::kNone; >> 169 mergingMode = "G4NtupleMergeMode::kNone"; >> 170 } >> 171 else { >> 172 // Set the number of reduced ntuple files >> 173 // G4int nofThreads = G4Threading::GetNumberOfThreads(); >> 174 fNofNtupleFiles = nofNtupleFiles; >> 175 >> 176 // Check the number of reduced ntuple files >> 177 // if ( fNofNtupleFiles < 0 || fNofNtupleFiles > nofThreads ) { >> 178 if ( fNofNtupleFiles < 0 ) { >> 179 G4ExceptionDescription description; >> 180 description >> 181 << " " << "Number of reduced files must be [0, nofThreads]." >> 182 << G4endl >> 183 << " " << "Cannot set " << nofNtupleFiles >> 184 // << " files when nofThreads is " << nofThreads << G4endl >> 185 << " files" << G4endl >> 186 << " " << "Ntuples will be merged in a single file."; >> 187 G4Exception("G4RootAnalysisManager::SetNtupleMergingMode()", >> 188 "Analysis_W013", JustWarning, description); >> 189 fNofNtupleFiles = 0; >> 190 } >> 191 >> 192 // if ( fNofNtupleFiles == nofThreads ) { >> 193 // // add warning that no merging will be applied >> 194 // fNtupleMergeMode = G4NtupleMergeMode::kNone; >> 195 // fNofNtupleFiles = 0; >> 196 // mergingMode = "G4NtupleMergeMode::kNone"; >> 197 // } >> 198 // else { >> 199 // G4bool isMaster = ! G4Threading::IsWorkerThread(); >> 200 // if ( isMaster ) { >> 201 // fNtupleMergeMode = G4NtupleMergeMode::kMain; >> 202 // mergingMode = "G4NtupleMergeMode::kMain"; >> 203 // } else { >> 204 // fNtupleMergeMode = G4NtupleMergeMode::kSlave; >> 205 // mergingMode = "G4NtupleMergeMode::kSlave"; >> 206 // } >> 207 // } >> 208 >> 209 // Forced merging mode >> 210 G4bool isMaster = ! G4Threading::IsWorkerThread(); >> 211 if ( isMaster ) { >> 212 fNtupleMergeMode = G4NtupleMergeMode::kMain; >> 213 mergingMode = "G4NtupleMergeMode::kMain"; >> 214 } else { >> 215 fNtupleMergeMode = G4NtupleMergeMode::kSlave; >> 216 mergingMode = "G4NtupleMergeMode::kSlave"; >> 217 } >> 218 } >> 219 >> 220 #ifdef G4VERBOSE >> 221 if ( fState.GetVerboseL2() ) >> 222 fState.GetVerboseL2() >> 223 ->Message("set", "ntuple merging mode", mergingMode); >> 224 #endif 83 } 225 } 84 226 85 //____________________________________________ 227 //_____________________________________________________________________________ 86 void G4RootAnalysisManager::SetNtupleRowWise(G << 228 void G4RootAnalysisManager::ClearNtupleManagers() 87 { 229 { 88 fNtupleFileManager->SetNtupleRowWise(rowWise << 230 #ifdef G4VERBOSE >> 231 if ( fState.GetVerboseL4() ) >> 232 fState.GetVerboseL4()->Message("clear", "ntuple managers", ""); >> 233 #endif >> 234 >> 235 if ( fNtupleMergeMode != G4NtupleMergeMode::kSlave ) { >> 236 // Do not reset master ntuple manager >> 237 delete fNtupleManager; >> 238 fNtupleManager = nullptr; >> 239 // SetNtupleManager(fNtupleManager); >> 240 } >> 241 >> 242 delete fSlaveNtupleManager; >> 243 fSlaveNtupleManager = nullptr; >> 244 >> 245 #ifdef G4VERBOSE >> 246 if ( fState.GetVerboseL3() ) >> 247 fState.GetVerboseL3()->Message("clear", "ntuple managers", ""); >> 248 #endif 89 } 249 } 90 250 91 //____________________________________________ 251 //_____________________________________________________________________________ 92 void G4RootAnalysisManager::SetBasketSize(unsi << 252 void G4RootAnalysisManager::CreateNtupleManagers() 93 { 253 { 94 fFileManager->SetBasketSize(basketSize); << 254 #ifdef G4VERBOSE >> 255 if ( fState.GetVerboseL4() ) >> 256 fState.GetVerboseL4()->Message("create", "ntuple managers", ""); >> 257 #endif >> 258 >> 259 switch ( fNtupleMergeMode ) >> 260 { >> 261 case G4NtupleMergeMode::kNone: >> 262 fNtupleManager = new G4RootNtupleManager(fState); >> 263 fNtupleManager->SetFileManager(fFileManager); >> 264 SetNtupleManager(fNtupleManager); >> 265 break; >> 266 >> 267 case G4NtupleMergeMode::kMain: { >> 268 G4int nofMainManagers = fNofNtupleFiles; >> 269 if ( ! nofMainManagers ) nofMainManagers = 1; >> 270 // create one manager if merging required into the histos & profiles files >> 271 fNtupleManager = new G4RootNtupleManager(fState, nofMainManagers); >> 272 fNtupleManager->SetFileManager(fFileManager); >> 273 SetNtupleManager(fNtupleManager); >> 274 break; >> 275 } >> 276 >> 277 case G4NtupleMergeMode::kSlave: >> 278 fNtupleManager = fgMasterInstance->fNtupleManager; >> 279 // The master class is used only in Get* functions >> 280 auto mainNtupleManager >> 281 = fNtupleManager->GetMainNtupleManager(GetNtupleFileNumber()); >> 282 fSlaveNtupleManager = new G4RootPNtupleManager(mainNtupleManager, fState); >> 283 SetNtupleManager(fSlaveNtupleManager); >> 284 break; >> 285 } >> 286 >> 287 #ifdef G4VERBOSE >> 288 if ( fState.GetVerboseL3() ) >> 289 fState.GetVerboseL3()->Message("create", "ntuple managers", ""); >> 290 #endif >> 291 } >> 292 >> 293 //_____________________________________________________________________________ >> 294 G4int G4RootAnalysisManager::GetNtupleFileNumber() >> 295 { >> 296 if ( ! fNofNtupleFiles ) return 0; >> 297 >> 298 G4int nofMainManagers = fNofNtupleFiles; >> 299 if ( ! nofMainManagers ) nofMainManagers = 1; >> 300 >> 301 // Debug - check G4Threading::GetNumberOfRunningWorkerThreads() >> 302 G4cout << "In GetNtupleFileNumber: " >> 303 << G4Threading::GetNumberOfRunningWorkerThreads() << G4endl; >> 304 >> 305 auto fileNumber = G4Threading::G4GetThreadId() % nofMainManagers; >> 306 return fileNumber; >> 307 } >> 308 >> 309 //_____________________________________________________________________________ >> 310 G4bool G4RootAnalysisManager::WriteH1() >> 311 { >> 312 auto h1Vector = fH1Manager->GetH1Vector(); >> 313 auto hnVector = fH1Manager->GetHnVector(); >> 314 >> 315 if ( ! h1Vector.size() ) return true; >> 316 >> 317 auto result = true; >> 318 >> 319 if ( ! G4Threading::IsWorkerThread() ) { >> 320 auto directory = fFileManager->GetHistoDirectory(); >> 321 result = WriteT(h1Vector, hnVector, directory, "h1"); >> 322 } >> 323 else { >> 324 // The worker manager just adds its histograms to the master >> 325 // This operation needs a lock >> 326 G4AutoLock lH1(&mergeH1Mutex); >> 327 fgMasterInstance->fH1Manager->AddH1Vector(h1Vector); >> 328 lH1.unlock(); >> 329 } >> 330 >> 331 return result; >> 332 } >> 333 >> 334 //_____________________________________________________________________________ >> 335 G4bool G4RootAnalysisManager::WriteH2() >> 336 { >> 337 auto h2Vector = fH2Manager->GetH2Vector(); >> 338 auto hnVector = fH2Manager->GetHnVector(); >> 339 >> 340 if ( ! h2Vector.size() ) return true; >> 341 >> 342 auto result = true; >> 343 >> 344 if ( ! G4Threading::IsWorkerThread() ) { >> 345 auto directory = fFileManager->GetHistoDirectory(); >> 346 result = WriteT(h2Vector, hnVector, directory, "h2"); >> 347 } >> 348 else { >> 349 // The worker manager just adds its histograms to the master >> 350 // This operation needs a lock >> 351 G4AutoLock lH2(&mergeH2Mutex); >> 352 fgMasterInstance->fH2Manager->AddH2Vector(h2Vector); >> 353 lH2.unlock(); >> 354 } >> 355 >> 356 return result; >> 357 } >> 358 >> 359 //_____________________________________________________________________________ >> 360 G4bool G4RootAnalysisManager::WriteH3() >> 361 { >> 362 auto h3Vector = fH3Manager->GetH3Vector(); >> 363 auto hnVector = fH3Manager->GetHnVector(); >> 364 >> 365 if ( ! h3Vector.size() ) return true; >> 366 >> 367 auto result = true; >> 368 >> 369 if ( ! G4Threading::IsWorkerThread() ) { >> 370 auto directory = fFileManager->GetHistoDirectory(); >> 371 result = WriteT(h3Vector, hnVector, directory, "h3"); >> 372 } >> 373 else { >> 374 // The worker manager just adds its histograms to the master >> 375 // This operation needs a lock >> 376 G4AutoLock lH3(&mergeH3Mutex); >> 377 fgMasterInstance->fH3Manager->AddH3Vector(h3Vector); >> 378 lH3.unlock(); >> 379 } >> 380 >> 381 return result; >> 382 } >> 383 >> 384 //_____________________________________________________________________________ >> 385 G4bool G4RootAnalysisManager::WriteP1() >> 386 { >> 387 auto p1Vector = fP1Manager->GetP1Vector(); >> 388 auto hnVector = fP1Manager->GetHnVector(); >> 389 >> 390 if ( ! p1Vector.size() ) return true; >> 391 >> 392 auto result = true; >> 393 >> 394 if ( ! G4Threading::IsWorkerThread() ) { >> 395 auto directory = fFileManager->GetHistoDirectory(); >> 396 result = WriteT(p1Vector, hnVector, directory, "p1"); >> 397 } >> 398 else { >> 399 // The worker manager just adds its histograms to the master >> 400 // This operation needs a lock >> 401 G4AutoLock lP1(&mergeP1Mutex); >> 402 fgMasterInstance->fP1Manager->AddP1Vector(p1Vector); >> 403 lP1.unlock(); >> 404 } >> 405 >> 406 return result; >> 407 } >> 408 >> 409 //_____________________________________________________________________________ >> 410 G4bool G4RootAnalysisManager::WriteP2() >> 411 { >> 412 auto p2Vector = fP2Manager->GetP2Vector(); >> 413 auto hnVector = fP2Manager->GetHnVector(); >> 414 >> 415 if ( ! p2Vector.size() ) return true; >> 416 >> 417 auto result = true; >> 418 >> 419 if ( ! G4Threading::IsWorkerThread() ) { >> 420 auto directory = fFileManager->GetHistoDirectory(); >> 421 result = WriteT(p2Vector, hnVector, directory, "p2"); >> 422 } >> 423 else { >> 424 // The worker manager just adds its histograms to the master >> 425 // This operation needs a lock >> 426 G4AutoLock lP2(&mergeP2Mutex); >> 427 fgMasterInstance->fP2Manager->AddP2Vector(p2Vector); >> 428 lP2.unlock(); >> 429 } >> 430 >> 431 return result; >> 432 } >> 433 >> 434 //_____________________________________________________________________________ >> 435 G4bool G4RootAnalysisManager::WriteNtuple() >> 436 { >> 437 if ( fNtupleMergeMode == G4NtupleMergeMode::kNone ) return true; >> 438 >> 439 auto finalResult = true; >> 440 >> 441 G4String ntupleType; >> 442 if ( fNtupleMergeMode == G4NtupleMergeMode::kMain ) ntupleType = "main ntuples"; >> 443 if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave ) ntupleType = "slave ntuples"; >> 444 >> 445 #ifdef G4VERBOSE >> 446 if ( fState.GetVerboseL4() ) >> 447 fState.GetVerboseL4()->Message("merge", ntupleType, ""); >> 448 #endif >> 449 >> 450 if ( fNtupleMergeMode == G4NtupleMergeMode::kMain ) { >> 451 auto result = fNtupleManager->Merge(); >> 452 finalResult = result && finalResult; >> 453 } >> 454 >> 455 if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave ) { >> 456 auto result = fSlaveNtupleManager->Merge(); >> 457 finalResult = result && finalResult; >> 458 } >> 459 >> 460 #ifdef G4VERBOSE >> 461 if ( fState.GetVerboseL1() ) >> 462 fState.GetVerboseL1()->Message("merge", ntupleType, ""); >> 463 #endif >> 464 >> 465 return finalResult; >> 466 } >> 467 >> 468 //_____________________________________________________________________________ >> 469 G4bool G4RootAnalysisManager::Reset() >> 470 { >> 471 // Reset histograms and ntuple >> 472 >> 473 auto finalResult = true; >> 474 >> 475 auto result = G4ToolsAnalysisManager::Reset(); >> 476 finalResult = finalResult && result; >> 477 >> 478 if ( fNtupleMergeMode == G4NtupleMergeMode::kNone || >> 479 fNtupleMergeMode == G4NtupleMergeMode::kMain ) { >> 480 result = fNtupleManager->Reset(false); >> 481 finalResult = result && finalResult; >> 482 } >> 483 >> 484 finalResult = finalResult && result; >> 485 >> 486 return finalResult; >> 487 } >> 488 >> 489 // >> 490 // protected methods >> 491 // >> 492 >> 493 //_____________________________________________________________________________ >> 494 G4bool G4RootAnalysisManager::OpenFileImpl(const G4String& fileName) >> 495 { >> 496 auto finalResult = true; >> 497 auto result = fFileManager->SetFileName(fileName); >> 498 finalResult = finalResult && result; >> 499 >> 500 if ( fNtupleMergeMode == G4NtupleMergeMode::kNone ) { >> 501 >> 502 #ifdef G4VERBOSE >> 503 G4String name = fFileManager->GetFullFileName(); >> 504 if ( fState.GetVerboseL4() ) >> 505 fState.GetVerboseL4()->Message("open", "analysis file", name); >> 506 #endif >> 507 >> 508 result = fFileManager->OpenFile(fileName); >> 509 finalResult = finalResult && result; >> 510 >> 511 fNtupleManager->SetNtupleDirectory(fFileManager->GetNtupleDirectory()); >> 512 fNtupleManager->CreateNtuplesFromBooking(); >> 513 >> 514 #ifdef G4VERBOSE >> 515 if ( fState.GetVerboseL1() ) >> 516 fState.GetVerboseL1()->Message("open", "analysis file", name, finalResult); >> 517 #endif >> 518 >> 519 } >> 520 >> 521 if ( fNtupleMergeMode == G4NtupleMergeMode::kMain ) { >> 522 >> 523 #ifdef G4VERBOSE >> 524 G4String name = fFileManager->GetFullFileName(); >> 525 if ( fState.GetVerboseL4() ) >> 526 fState.GetVerboseL4()->Message("open", "main analysis file", name); >> 527 #endif >> 528 >> 529 fFileManager->SetNofNtupleFiles(fNofNtupleFiles); >> 530 result = fFileManager->OpenFile(fileName); >> 531 finalResult = finalResult && result; >> 532 >> 533 fNtupleManager->CreateNtuplesFromBooking(); >> 534 >> 535 #ifdef G4VERBOSE >> 536 if ( fState.GetVerboseL1() ) >> 537 fState.GetVerboseL1()->Message("open", "main analysis file", name, finalResult); >> 538 #endif >> 539 } >> 540 >> 541 if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave ) { >> 542 // No file is open by Slave manager >> 543 fSlaveNtupleManager->CreateNtuplesFromMain(); >> 544 } >> 545 >> 546 return finalResult; >> 547 } >> 548 >> 549 //_____________________________________________________________________________ >> 550 G4bool G4RootAnalysisManager::WriteImpl() >> 551 { >> 552 >> 553 auto finalResult = true; >> 554 >> 555 if ( ! fgMasterInstance && >> 556 ( ( ! fH1Manager->IsEmpty() ) || ( ! fH2Manager->IsEmpty() ) || >> 557 ( ! fH3Manager->IsEmpty() ) || ( ! fP1Manager->IsEmpty() ) || >> 558 ( ! fP2Manager->IsEmpty() ) ) ) { >> 559 G4ExceptionDescription description; >> 560 description >> 561 << " " << "No master G4RootAnalysisManager instance exists." >> 562 << G4endl >> 563 << " " << "Histogram/profile data will not be merged."; >> 564 G4Exception("G4RootAnalysisManager::Write()", >> 565 "Analysis_W031", JustWarning, description); >> 566 } >> 567 >> 568 // H1 >> 569 auto result = WriteH1(); >> 570 finalResult = finalResult && result; >> 571 >> 572 // H2 >> 573 result = WriteH2(); >> 574 finalResult = finalResult && result; >> 575 >> 576 // H3 >> 577 result = WriteH3(); >> 578 finalResult = finalResult && result; >> 579 >> 580 // P1 >> 581 result = WriteP1(); >> 582 finalResult = finalResult && result; >> 583 >> 584 // P2 >> 585 result = WriteP2(); >> 586 finalResult = finalResult && result; >> 587 >> 588 // Ntuples >> 589 result = WriteNtuple(); >> 590 finalResult = finalResult && result; >> 591 >> 592 // File >> 593 if ( fNtupleMergeMode != G4NtupleMergeMode::kSlave ) { >> 594 result = fFileManager->WriteFile(); >> 595 finalResult = finalResult && result; >> 596 } >> 597 >> 598 // Write ASCII if activated >> 599 if ( IsAscii() ) { >> 600 result = WriteAscii(fFileManager->GetFileName()); >> 601 finalResult = finalResult && result; >> 602 } >> 603 >> 604 return finalResult; >> 605 } >> 606 >> 607 //_____________________________________________________________________________ >> 608 G4bool G4RootAnalysisManager::CloseFileImpl() >> 609 { >> 610 auto finalResult = true; >> 611 >> 612 G4bool isNtupleManagerEmpty = fNtupleManager->IsEmpty(); >> 613 // the ntuple decription vector is cleared on Reset() >> 614 // in kNoMergeAfterOpen ntuple manager mode >> 615 >> 616 // reset data >> 617 auto result = Reset(); >> 618 if ( ! result ) { >> 619 G4ExceptionDescription description; >> 620 description << " " << "Resetting data failed"; >> 621 G4Exception("G4RootAnalysisManager::Write()", >> 622 "Analysis_W021", JustWarning, description); >> 623 } >> 624 finalResult = finalResult && result; >> 625 >> 626 if ( fNtupleMergeMode != G4NtupleMergeMode::kSlave ) { >> 627 // close file >> 628 fFileManager->CloseFile(); >> 629 } >> 630 >> 631 // No files clean-up in sequential mode >> 632 if ( ! G4Threading::IsMultithreadedApplication() ) return finalResult; >> 633 >> 634 // Delete files if empty in MT mode >> 635 if ( ( fState.GetIsMaster() && >> 636 fH1Manager->IsEmpty() && fH2Manager->IsEmpty() && fH3Manager->IsEmpty() && >> 637 fP1Manager->IsEmpty() && fP2Manager->IsEmpty() && isNtupleManagerEmpty ) || >> 638 ( ( ! fState.GetIsMaster() ) && isNtupleManagerEmpty && >> 639 fNtupleMergeMode == G4NtupleMergeMode::kNone ) ) { >> 640 result = ! std::remove(fFileManager->GetFullFileName()); >> 641 // std::remove returns 0 when success >> 642 if ( ! result ) { >> 643 G4ExceptionDescription description; >> 644 description << " " << "Removing file " >> 645 << fFileManager->GetFullFileName() << " failed"; >> 646 G4Exception("G4XmlAnalysisManager::CloseFile()", >> 647 "Analysis_W021", JustWarning, description); >> 648 } >> 649 finalResult = finalResult && result; >> 650 #ifdef G4VERBOSE >> 651 if ( fState.GetVerboseL1() ) >> 652 fState.GetVerboseL1() >> 653 ->Message("delete", "empty file", fFileManager->GetFullFileName()); >> 654 #endif >> 655 } >> 656 >> 657 return finalResult; 95 } 658 } 96 659 >> 660 // >> 661 // public methods >> 662 // >> 663 97 //____________________________________________ 664 //_____________________________________________________________________________ 98 void G4RootAnalysisManager::SetBasketEntries(u << 665 void G4RootAnalysisManager::SetNtupleMerging(G4bool mergeNtuples, >> 666 G4int nofNtupleFiles, >> 667 unsigned int basketSize) >> 668 99 { 669 { 100 fFileManager->SetBasketEntries(basketEntries << 670 // Keep basketSize in file manager >> 671 fFileManager->SetBasketSize(basketSize); >> 672 >> 673 // Set ntuple merging mode >> 674 SetNtupleMergingMode(mergeNtuples, nofNtupleFiles); >> 675 >> 676 // Clear existing managers >> 677 ClearNtupleManagers(); >> 678 >> 679 // Re-create managers >> 680 CreateNtupleManagers(); 101 } 681 } 102 682