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 74257 2013-10-02 14:24:55Z 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 "G4H1ToolsManager.hh" 32 #include "G4AnalysisManagerState.hh" << 33 #include "G4H2ToolsManager.hh" 33 #include "G4AnalysisUtilities.hh" << 34 #include "G4XmlNtupleManager.hh" 34 #include "G4ThreadLocalSingleton.hh" << 35 #include "G4Threading.hh" 35 #include "G4Threading.hh" >> 36 #include "G4AutoLock.hh" 36 37 37 using namespace G4Analysis; << 38 #include "tools/waxml/histos" 38 using std::make_shared; << 39 >> 40 // mutex in a file scope >> 41 >> 42 namespace { >> 43 //Mutex to lock master manager when merging H1 histograms >> 44 G4Mutex mergeH1Mutex = G4MUTEX_INITIALIZER; >> 45 //Mutex to lock master manager when merging H1 histograms >> 46 G4Mutex mergeH2Mutex = G4MUTEX_INITIALIZER; >> 47 } >> 48 >> 49 G4XmlAnalysisManager* G4XmlAnalysisManager::fgMasterInstance = 0; >> 50 G4ThreadLocal G4XmlAnalysisManager* G4XmlAnalysisManager::fgInstance = 0; 39 51 40 //____________________________________________ 52 //_____________________________________________________________________________ 41 G4XmlAnalysisManager* G4XmlAnalysisManager::In 53 G4XmlAnalysisManager* G4XmlAnalysisManager::Instance() 42 { 54 { 43 static G4ThreadLocalSingleton<G4XmlAnalysisM << 55 if ( fgInstance == 0 ) { 44 fgIsInstance = true; << 56 G4bool isMaster = ! G4Threading::IsWorkerThread(); 45 return instance.Instance(); << 57 fgInstance = new G4XmlAnalysisManager(isMaster); >> 58 } >> 59 >> 60 return fgInstance; >> 61 } >> 62 >> 63 //_____________________________________________________________________________ >> 64 G4XmlAnalysisManager::G4XmlAnalysisManager(G4bool isMaster) >> 65 : G4VAnalysisManager("Xml", isMaster), >> 66 fH1Manager(0), >> 67 fH2Manager(0), >> 68 fNtupleManager(0), >> 69 fFileManager(0) >> 70 { >> 71 if ( ( isMaster && fgMasterInstance ) || ( fgInstance ) ) { >> 72 G4ExceptionDescription description; >> 73 description >> 74 << " " >> 75 << "G4XmlAnalysisManager already exists." >> 76 << "Cannot create another instance."; >> 77 G4Exception("G4XmlAnalysisManager::G4XmlAnalysisManager", >> 78 "Analysis_F001", FatalException, description); >> 79 } >> 80 if ( isMaster ) fgMasterInstance = this; >> 81 fgInstance = this; >> 82 >> 83 // Create managers >> 84 fH1Manager = new G4H1ToolsManager(fState); >> 85 fH2Manager = new G4H2ToolsManager(fState); >> 86 fNtupleManager = new G4XmlNtupleManager(fState); >> 87 fFileManager = new G4XmlFileManager(fState); >> 88 fNtupleManager->SetFileManager(fFileManager); >> 89 // The managers will be deleted by the base class >> 90 >> 91 // Set managers to base class >> 92 SetH1Manager(fH1Manager); >> 93 SetH2Manager(fH2Manager); >> 94 SetNtupleManager(fNtupleManager); >> 95 SetFileManager(fFileManager); 46 } 96 } 47 97 48 //____________________________________________ 98 //_____________________________________________________________________________ 49 G4bool G4XmlAnalysisManager::IsInstance() << 99 G4XmlAnalysisManager::~G4XmlAnalysisManager() >> 100 { >> 101 if ( fState.GetIsMaster() ) fgMasterInstance = 0; >> 102 fgInstance = 0; >> 103 } >> 104 >> 105 // >> 106 // private methods >> 107 // >> 108 >> 109 //_____________________________________________________________________________ >> 110 G4bool G4XmlAnalysisManager::WriteH1() 50 { 111 { 51 return fgIsInstance; << 112 const std::vector<tools::histo::h1d*>& h1Vector >> 113 = fH1Manager->GetH1Vector(); >> 114 const std::vector<G4HnInformation*>& hnVector >> 115 = fH1Manager->GetHnVector(); >> 116 >> 117 if ( ! h1Vector.size() ) return true; >> 118 >> 119 if ( ! G4Threading::IsWorkerThread() ) { >> 120 >> 121 for ( G4int i=0; i<G4int(h1Vector.size()); ++i ) { >> 122 G4HnInformation* info = hnVector[i]; >> 123 G4bool activation = info->fActivation; >> 124 G4String name = info->fName; >> 125 // skip writing if activation is enabled and H1 is inactivated >> 126 if ( fState.GetIsActivation() && ( ! activation ) ) continue; >> 127 tools::histo::h1d* h1 = h1Vector[i]; >> 128 #ifdef G4VERBOSE >> 129 if ( fState.GetVerboseL3() ) >> 130 fState.GetVerboseL3()->Message("write", "h1d", name); >> 131 #endif >> 132 G4String path = "/"; >> 133 path.append(fFileManager->GetHistoDirectoryName()); >> 134 std::ofstream* hnFile = fFileManager->GetHnFile(); >> 135 G4bool result >> 136 = tools::waxml::write(*hnFile, *h1, path, name); >> 137 if ( ! result ) { >> 138 G4ExceptionDescription description; >> 139 description << " " << "saving histogram " << name << " failed"; >> 140 G4Exception("G4XmlAnalysisManager::Write()", >> 141 "Analysis_W003", JustWarning, description); >> 142 return false; >> 143 } >> 144 fFileManager->LockHistoDirectoryName(); >> 145 } >> 146 } >> 147 else { >> 148 // The worker manager just adds its histograms to the master >> 149 // This operation needs a lock >> 150 G4AutoLock lH1(&mergeH1Mutex); >> 151 fgMasterInstance->fH1Manager->AddH1Vector(h1Vector); >> 152 lH1.unlock(); >> 153 } >> 154 >> 155 return true; 52 } 156 } >> 157 >> 158 //_____________________________________________________________________________ >> 159 G4bool G4XmlAnalysisManager::WriteH2() >> 160 { >> 161 const std::vector<tools::histo::h2d*>& h2Vector >> 162 = fH2Manager->GetH2Vector(); >> 163 const std::vector<G4HnInformation*>& hnVector >> 164 = fH2Manager->GetHnVector(); >> 165 >> 166 if ( ! h2Vector.size() ) return true; >> 167 >> 168 if ( ! G4Threading::IsWorkerThread() ) { >> 169 >> 170 // h2 histograms >> 171 for ( G4int i=0; i<G4int(h2Vector.size()); ++i ) { >> 172 G4HnInformation* info = hnVector[i]; >> 173 G4bool activation = info->fActivation; >> 174 G4String name = info->fName; >> 175 // skip writing if inactivated >> 176 if ( fState.GetIsActivation() && ( ! activation ) ) continue; >> 177 tools::histo::h2d* h2 = h2Vector[i]; >> 178 #ifdef G4VERBOSE >> 179 if ( fState.GetVerboseL3() ) >> 180 fState.GetVerboseL3()->Message("write", "h2d", name); >> 181 #endif >> 182 G4String path = "/"; >> 183 path.append(fFileManager->GetHistoDirectoryName()); >> 184 std::ofstream* hnFile = fFileManager->GetHnFile(); >> 185 G4bool result >> 186 = tools::waxml::write(*hnFile, *h2, path, name); >> 187 if ( ! result ) { >> 188 G4ExceptionDescription description; >> 189 description << " " << "saving histogram " << name << " failed"; >> 190 G4Exception("G4XmlAnalysisManager::Write()", >> 191 "Analysis_W003", JustWarning, description); >> 192 return false; >> 193 } >> 194 fFileManager->LockHistoDirectoryName(); >> 195 } >> 196 } >> 197 else { >> 198 // The worker manager just adds its histograms to the master >> 199 // This operation needs a lock >> 200 G4AutoLock lH2(&mergeH2Mutex); >> 201 fgMasterInstance->fH2Manager->AddH2Vector(h2Vector); >> 202 lH2.unlock(); >> 203 } >> 204 >> 205 return true; >> 206 } >> 207 >> 208 //_____________________________________________________________________________ >> 209 G4bool G4XmlAnalysisManager::WriteNtuple() >> 210 { >> 211 const std::vector<G4XmlNtupleDescription*>& ntupleVector >> 212 = fNtupleManager->GetNtupleVector(); >> 213 >> 214 for ( G4int i=0; i<G4int(ntupleVector.size()); ++i ) { >> 215 if ( ntupleVector[i]->fNtuple ) ntupleVector[i]->fNtuple->write_trailer(); >> 216 } >> 217 >> 218 return true; >> 219 } >> 220 >> 221 //_____________________________________________________________________________ >> 222 G4bool G4XmlAnalysisManager::CloseNtupleFiles() >> 223 { >> 224 const std::vector<G4XmlNtupleDescription*>& ntupleVector >> 225 = fNtupleManager->GetNtupleVector(); >> 226 >> 227 // Close ntuple files >> 228 std::vector<G4XmlNtupleDescription*>::const_iterator it; >> 229 for (it = ntupleVector.begin(); it != ntupleVector.end(); it++ ) { >> 230 fFileManager->CloseNtupleFile((*it)); >> 231 } >> 232 >> 233 return true; >> 234 } >> 235 53 236 54 //____________________________________________ 237 //_____________________________________________________________________________ 55 G4XmlAnalysisManager::G4XmlAnalysisManager() << 238 G4bool G4XmlAnalysisManager::Reset() 56 : G4ToolsAnalysisManager("Xml") << 57 { 239 { 58 // File Manager << 240 // Reset histograms and ntuple 59 auto fileManager = std::make_shared<G4XmlFil << 241 60 SetFileManager(fileManager); << 242 G4bool finalResult = true; 61 << 243 62 // Ntuple file manager << 244 G4bool result = fH1Manager->Reset(); 63 fNtupleFileManager = std::make_shared<G4XmlN << 245 finalResult = finalResult && result; 64 SetNtupleFileManager(fNtupleFileManager); << 246 65 fNtupleFileManager->SetFileManager(std::move << 247 result = fH2Manager->Reset(); 66 fNtupleFileManager->SetBookingManager(fNtupl << 248 finalResult = finalResult && result; >> 249 >> 250 result = fNtupleManager->Reset(); >> 251 finalResult = finalResult && result; >> 252 >> 253 return finalResult; >> 254 } >> 255 >> 256 // >> 257 // protected methods >> 258 // >> 259 >> 260 //_____________________________________________________________________________ >> 261 G4bool G4XmlAnalysisManager::OpenFileImpl(const G4String& fileName) >> 262 { >> 263 G4bool finalResult = true; >> 264 G4bool result = fFileManager->SetFileName(fileName); >> 265 finalResult = finalResult && result; >> 266 >> 267 #ifdef G4VERBOSE >> 268 G4String name = fFileManager->GetFullFileName(); >> 269 if ( fState.GetVerboseL4() ) { >> 270 fState.GetVerboseL4()->Message("open", "analysis file", name); >> 271 } >> 272 #endif >> 273 >> 274 // Only lock file name in file manager >> 275 result = fFileManager->OpenFile(fileName); >> 276 finalResult = finalResult && result; >> 277 >> 278 // Create histograms file (on master) >> 279 if ( fState.GetIsMaster() ) { >> 280 result = fFileManager->CreateHnFile(); >> 281 finalResult = finalResult && result; >> 282 } >> 283 >> 284 // Create ntuples if they are booked >> 285 // (The files will be created with creating ntuples) >> 286 fNtupleManager->CreateNtuplesFromBooking(); >> 287 >> 288 #ifdef G4VERBOSE >> 289 if ( fState.GetVerboseL1() ) >> 290 fState.GetVerboseL1()->Message("open", "analysis file", name); >> 291 #endif >> 292 >> 293 return finalResult; >> 294 } >> 295 >> 296 //_____________________________________________________________________________ >> 297 G4bool G4XmlAnalysisManager::WriteImpl() >> 298 { >> 299 G4bool finalResult = true; >> 300 >> 301 #ifdef G4VERBOSE >> 302 G4String name = fFileManager->GetFullFileName(); >> 303 if ( fState.GetVerboseL4() ) >> 304 fState.GetVerboseL4()->Message("write", "files", name); >> 305 #endif >> 306 >> 307 // ntuples >> 308 WriteNtuple(); >> 309 >> 310 if ( ! fgMasterInstance && >> 311 ( ( ! fH1Manager->IsEmpty() ) || ( ! fH2Manager->IsEmpty() ) ) ) { >> 312 >> 313 G4ExceptionDescription description; >> 314 description >> 315 << " " << "No master G4XmlAnalysisManager instance exists." >> 316 << G4endl >> 317 << " " << "Histogram data will not be merged."; >> 318 G4Exception("G4XmlAnalysisManager::Write()", >> 319 "Analysis_W014", JustWarning, description); >> 320 >> 321 // Create Hn file per thread >> 322 G4bool result = fFileManager->CreateHnFile(); >> 323 if ( ! result ) return false; >> 324 } >> 325 >> 326 // H1 >> 327 G4bool result = WriteH1(); >> 328 finalResult = finalResult && result; >> 329 >> 330 // H2 >> 331 result = WriteH2(); >> 332 finalResult = finalResult && result; >> 333 >> 334 // Write ASCII if activated >> 335 if ( IsAscii() ) { >> 336 result = WriteAscii(fFileManager->GetFileName()); >> 337 finalResult = finalResult && result; >> 338 } >> 339 >> 340 #ifdef G4VERBOSE >> 341 if ( fState.GetVerboseL1() ) >> 342 fState.GetVerboseL1() >> 343 ->Message("write", "files", fFileManager->GetFullFileName(), finalResult); >> 344 #endif >> 345 >> 346 return finalResult; 67 } 347 } 68 348 69 //____________________________________________ 349 //_____________________________________________________________________________ 70 G4XmlAnalysisManager::~G4XmlAnalysisManager() << 350 G4bool G4XmlAnalysisManager::CloseFileImpl() 71 { 351 { 72 fgIsInstance = false; << 352 G4bool finalResult = true; >> 353 >> 354 #ifdef G4VERBOSE >> 355 if ( fState.GetVerboseL4() ) >> 356 fState.GetVerboseL4()->Message("close", "files", ""); >> 357 #endif >> 358 >> 359 // Unlock file name only >> 360 G4bool result = fFileManager->CloseFile(); >> 361 finalResult = finalResult && result; >> 362 >> 363 // Close Hn file >> 364 result = fFileManager->CloseHnFile(); >> 365 finalResult = finalResult && result; >> 366 >> 367 // Close ntuple files >> 368 if ( ( ! G4AnalysisManagerState::IsMT() ) || ( ! fState.GetIsMaster() ) ) { >> 369 // In sequential mode or in MT mode only on workers >> 370 result = CloseNtupleFiles(); >> 371 finalResult = finalResult && result; >> 372 } >> 373 >> 374 // reset data >> 375 result = Reset(); >> 376 if ( ! result ) { >> 377 G4ExceptionDescription description; >> 378 description << " " << "Resetting data failed"; >> 379 G4Exception("G4XmlAnalysisManager::CloseFile()", >> 380 "Analysis_W002", JustWarning, description); >> 381 } >> 382 finalResult = finalResult && result; >> 383 >> 384 // delete files if empty >> 385 // (ntuple files are created only if an ntuple is created) >> 386 if ( fFileManager->GetHnFile() && >> 387 fH1Manager->IsEmpty() && fH2Manager->IsEmpty() ) { >> 388 std::remove(fFileManager->GetFullFileName()); >> 389 #ifdef G4VERBOSE >> 390 if ( fState.GetVerboseL1() ) >> 391 fState.GetVerboseL1() >> 392 ->Message("delete", "empty file", fFileManager->GetFullFileName()); >> 393 #endif >> 394 } >> 395 else { >> 396 #ifdef G4VERBOSE >> 397 if ( fState.GetVerboseL1() ) >> 398 fState.GetVerboseL1() >> 399 ->Message("close", "files", fFileManager->GetFullFileName()); >> 400 #endif >> 401 } >> 402 >> 403 return finalResult; 73 } 404 } 74 405