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