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, 09/04/2014 (ivana 27 // Author: Ivana Hrivnacova, 09/04/2014 (ivana@ipno.in2p3.fr) 28 28 29 #include "G4RootAnalysisReader.hh" 29 #include "G4RootAnalysisReader.hh" 30 #include "G4RootRFileManager.hh" 30 #include "G4RootRFileManager.hh" 31 #include "G4RootRNtupleManager.hh" 31 #include "G4RootRNtupleManager.hh" >> 32 #include "G4AnalysisVerbose.hh" 32 #include "G4AnalysisUtilities.hh" 33 #include "G4AnalysisUtilities.hh" 33 #include "G4ThreadLocalSingleton.hh" << 34 #include "G4Threading.hh" 34 #include "G4Threading.hh" 35 35 >> 36 #include <tools/rroot/file> >> 37 #include <tools/rroot/streamers> >> 38 #include <tools/rroot/fac> >> 39 #include <tools/rroot/tree> >> 40 #include <tools/rroot/ntuple> >> 41 >> 42 #include <iostream> >> 43 #include <cstdio> >> 44 36 using namespace G4Analysis; 45 using namespace G4Analysis; 37 46 >> 47 G4RootAnalysisReader* G4RootAnalysisReader::fgMasterInstance = nullptr; >> 48 G4ThreadLocal G4RootAnalysisReader* G4RootAnalysisReader::fgInstance = nullptr; >> 49 38 //____________________________________________ 50 //_____________________________________________________________________________ 39 G4RootAnalysisReader* G4RootAnalysisReader::In 51 G4RootAnalysisReader* G4RootAnalysisReader::Instance() 40 { 52 { 41 static G4ThreadLocalSingleton<G4RootAnalysis << 53 if ( fgInstance == nullptr ) { 42 return instance.Instance(); << 54 G4bool isMaster = ! G4Threading::IsWorkerThread(); 43 } << 55 fgInstance = new G4RootAnalysisReader(isMaster); >> 56 } >> 57 >> 58 return fgInstance; >> 59 } 44 60 45 //____________________________________________ 61 //_____________________________________________________________________________ 46 G4RootAnalysisReader::G4RootAnalysisReader() << 62 G4RootAnalysisReader::G4RootAnalysisReader(G4bool isMaster) 47 : G4ToolsAnalysisReader("Root") << 63 : G4ToolsAnalysisReader("Root", isMaster), >> 64 fNtupleManager(nullptr), >> 65 fFileManager(nullptr) 48 { 66 { 49 if ( ! G4Threading::IsWorkerThread() ) fgMas << 67 if ( ( isMaster && fgMasterInstance ) || ( fgInstance ) ) { >> 68 G4ExceptionDescription description; >> 69 description >> 70 << " " >> 71 << "G4RootAnalysisReader already exists." >> 72 << "Cannot create another instance."; >> 73 G4Exception("G4RootAnalysisReader::G4RootAnalysisReader()", >> 74 "Analysis_F001", FatalException, description); >> 75 } >> 76 if ( isMaster ) fgMasterInstance = this; >> 77 fgInstance = this; 50 78 51 // Create managers 79 // Create managers 52 fNtupleManager = std::make_shared<G4RootRNtu << 80 fNtupleManager = new G4RootRNtupleManager(fState); 53 fFileManager = std::make_shared<G4RootRFileM << 81 fFileManager = new G4RootRFileManager(fState); 54 fNtupleManager->SetFileManager(fFileManager) << 82 // The managers will be deleted by the base class 55 << 83 56 // Set managers to base class 84 // Set managers to base class 57 SetNtupleManager(fNtupleManager); 85 SetNtupleManager(fNtupleManager); 58 SetFileManager(fFileManager); 86 SetFileManager(fFileManager); 59 } 87 } 60 88 61 //____________________________________________ 89 //_____________________________________________________________________________ 62 G4RootAnalysisReader::~G4RootAnalysisReader() 90 G4RootAnalysisReader::~G4RootAnalysisReader() 63 { 91 { 64 if ( fState.GetIsMaster() ) fgMasterInstance 92 if ( fState.GetIsMaster() ) fgMasterInstance = nullptr; >> 93 fgInstance = nullptr; 65 } 94 } 66 95 67 // << 96 // 68 // private methods 97 // private methods 69 // 98 // 70 99 71 //____________________________________________ 100 //_____________________________________________________________________________ >> 101 tools::rroot::buffer* G4RootAnalysisReader::GetBuffer( >> 102 const G4String& fileName, >> 103 const G4String& objectName, >> 104 const G4String& inFunction) >> 105 { >> 106 // Get buffer for reading histogram or profile specified by objectNmae >> 107 // for a file specified by fileName; >> 108 // open the file if it was not yet open >> 109 >> 110 // Histograms and profiles are not saved per thread >> 111 G4bool isPerThread = false; >> 112 >> 113 // Get or open a file >> 114 auto rfile = fFileManager->GetRFile(fileName, isPerThread); >> 115 if ( ! rfile ) { >> 116 if ( ! fFileManager->OpenRFile(fileName, isPerThread) ) return nullptr; >> 117 rfile = fFileManager->GetRFile(fileName, isPerThread); >> 118 } >> 119 >> 120 auto key >> 121 = ( ! rfile ) ? nullptr : rfile->dir().find_key(objectName); >> 122 >> 123 unsigned int size; >> 124 //char* charBuffer >> 125 // = ( ! key ) ? 0 : key->get_object_buffer(size); >> 126 char* charBuffer = 0; >> 127 if ( key ) charBuffer = key->get_object_buffer(*rfile, size); >> 128 >> 129 if ( ! charBuffer ) { >> 130 G4ExceptionDescription description; >> 131 description >> 132 << " " >> 133 << "Cannot get " << objectName << " in file " << fileName; >> 134 G4Exception(inFunction, "Analysis_WR011", JustWarning, description); >> 135 return nullptr; >> 136 } >> 137 >> 138 auto verbose = false; >> 139 return new tools::rroot::buffer(G4cout, rfile->byte_swap(), size, charBuffer, >> 140 key->key_length(), verbose); >> 141 } >> 142 >> 143 //_____________________________________________________________________________ 72 G4bool G4RootAnalysisReader::Reset() 144 G4bool G4RootAnalysisReader::Reset() 73 { 145 { 74 // Reset histograms and ntuple 146 // Reset histograms and ntuple 75 147 76 auto result = true; << 148 auto finalResult = true; >> 149 >> 150 auto result = G4ToolsAnalysisReader::Reset(); >> 151 finalResult = finalResult && result; >> 152 >> 153 result = fNtupleManager->Reset(); >> 154 finalResult = finalResult && result; >> 155 >> 156 return finalResult; >> 157 } >> 158 >> 159 // >> 160 // protected methods >> 161 // 77 162 78 result &= G4ToolsAnalysisReader::Reset(); << 163 //_____________________________________________________________________________ 79 result &= fNtupleManager->Reset(); << 164 G4int G4RootAnalysisReader::ReadH1Impl(const G4String& h1Name, >> 165 const G4String& fileName, >> 166 const G4String& /*dirName*/, >> 167 G4bool /*isUserFileName*/) >> 168 { >> 169 #ifdef G4VERBOSE >> 170 if ( fState.GetVerboseL4() ) >> 171 fState.GetVerboseL4()->Message("read", "h1", h1Name); >> 172 #endif >> 173 >> 174 auto buffer = GetBuffer(fileName, h1Name, "ReadH1Impl"); >> 175 if ( ! buffer ) return kInvalidId; >> 176 >> 177 auto h1 = tools::rroot::TH1D_stream(*buffer); >> 178 delete buffer; >> 179 >> 180 if ( ! h1 ) { >> 181 G4ExceptionDescription description; >> 182 description >> 183 << " " >> 184 << "Streaming " << h1Name << " in file " << fileName << " failed."; >> 185 G4Exception("G4RootAnalysisReader::ReadH1Impl", >> 186 "Analysis_WR011", JustWarning, description); >> 187 return kInvalidId; >> 188 } >> 189 >> 190 auto id = fH1Manager->AddH1(h1Name, h1); >> 191 >> 192 #ifdef G4VERBOSE >> 193 if ( fState.GetVerboseL2() ) >> 194 fState.GetVerboseL2()->Message("read", "h1", h1Name, id > kInvalidId); >> 195 #endif >> 196 >> 197 return id; >> 198 } 80 199 81 return result; << 200 //_____________________________________________________________________________ 82 } << 201 G4int G4RootAnalysisReader::ReadH2Impl(const G4String& h2Name, >> 202 const G4String& fileName, >> 203 const G4String& /*dirName*/, >> 204 G4bool /*isUserFileName*/) >> 205 { >> 206 #ifdef G4VERBOSE >> 207 if ( fState.GetVerboseL4() ) >> 208 fState.GetVerboseL4()->Message("read", "h2", h2Name); >> 209 #endif >> 210 >> 211 auto buffer = GetBuffer(fileName, h2Name, "ReadH2Impl"); >> 212 if ( ! buffer ) return kInvalidId; >> 213 >> 214 // if h2Name represents H1, then we get !! >> 215 // tools::rroot::buffer::check_byte_count : object of class "TNamed" read too few bytes (603979762 missing). >> 216 // tools::rroot::buffer::check_byte_count : "TNamed" streamer not in sync with data on file, fix streamer. >> 217 // Segmentation fault (core dumped) >> 218 >> 219 auto h2 = tools::rroot::TH2D_stream(*buffer); >> 220 delete buffer; >> 221 >> 222 if ( ! h2 ) { >> 223 G4ExceptionDescription description; >> 224 description >> 225 << " " >> 226 << "Streaming " << h2Name << " in file " << fileName << " failed."; >> 227 G4Exception("G4RootAnalysisReader::ReadH2Impl", >> 228 "Analysis_WR011", JustWarning, description); >> 229 return kInvalidId; >> 230 } >> 231 >> 232 auto id = fH2Manager->AddH2(h2Name, h2); >> 233 >> 234 #ifdef G4VERBOSE >> 235 if ( fState.GetVerboseL2() ) >> 236 fState.GetVerboseL2()->Message("read", "h2", h2Name, id > kInvalidId); >> 237 #endif >> 238 >> 239 return id; >> 240 } 83 241 84 // << 242 //_____________________________________________________________________________ 85 // protected methods << 243 G4int G4RootAnalysisReader::ReadH3Impl(const G4String& h3Name, 86 // << 244 const G4String& fileName, >> 245 const G4String& /*dirName*/, >> 246 G4bool /*isUserFileName*/) >> 247 { >> 248 >> 249 #ifdef G4VERBOSE >> 250 if ( fState.GetVerboseL4() ) >> 251 fState.GetVerboseL4()->Message("read", "h3", h3Name); >> 252 #endif >> 253 >> 254 auto buffer = GetBuffer(fileName, h3Name, "ReadH3Impl"); >> 255 if ( ! buffer ) return kInvalidId; >> 256 >> 257 auto h3 = tools::rroot::TH3D_stream(*buffer); >> 258 delete buffer; >> 259 >> 260 if ( ! h3 ) { >> 261 G4ExceptionDescription description; >> 262 description >> 263 << " " >> 264 << "Streaming " << h3Name << " in file " << fileName << " failed."; >> 265 G4Exception("G4RootAnalysisReader::ReadH3Impl", >> 266 "Analysis_WR011", JustWarning, description); >> 267 return kInvalidId; >> 268 } >> 269 >> 270 auto id = fH3Manager->AddH3(h3Name, h3); >> 271 >> 272 #ifdef G4VERBOSE >> 273 if ( fState.GetVerboseL2() ) >> 274 fState.GetVerboseL2()->Message("read", "h3", h3Name, id > kInvalidId); >> 275 #endif >> 276 >> 277 return id; >> 278 /* >> 279 // not yet available >> 280 return kInvalidId; >> 281 */ >> 282 } 87 283 88 //____________________________________________ 284 //_____________________________________________________________________________ 89 G4bool G4RootAnalysisReader::CloseFilesImpl(G << 285 G4int G4RootAnalysisReader::ReadP1Impl(const G4String& p1Name, >> 286 const G4String& fileName, >> 287 const G4String& /*dirName*/, >> 288 G4bool /*isUserFileName*/) 90 { 289 { 91 Message(kVL4, "close", "files"); << 290 #ifdef G4VERBOSE >> 291 if ( fState.GetVerboseL4() ) >> 292 fState.GetVerboseL4()->Message("read", "p1", p1Name); >> 293 #endif >> 294 >> 295 auto buffer = GetBuffer(fileName, p1Name, "ReadP1Impl"); >> 296 if ( ! buffer ) return kInvalidId; >> 297 >> 298 auto p1 = tools::rroot::TProfile_stream(*buffer); >> 299 delete buffer; >> 300 >> 301 if ( ! p1 ) { >> 302 G4ExceptionDescription description; >> 303 description >> 304 << " " >> 305 << "Streaming " << p1Name << " in file " << fileName << " failed."; >> 306 G4Exception("G4RootAnalysisReader::ReadP1Impl", >> 307 "Analysis_WR011", JustWarning, description); >> 308 return kInvalidId; >> 309 } >> 310 >> 311 auto id = fP1Manager->AddP1(p1Name, p1); >> 312 >> 313 #ifdef G4VERBOSE >> 314 if ( fState.GetVerboseL2() ) >> 315 fState.GetVerboseL2()->Message("read", "p1", p1Name, id > kInvalidId); >> 316 #endif >> 317 >> 318 return id; >> 319 } 92 320 93 auto result = true; << 321 //_____________________________________________________________________________ >> 322 G4int G4RootAnalysisReader::ReadP2Impl(const G4String& p2Name, >> 323 const G4String& fileName, >> 324 const G4String& /*dirName*/, >> 325 G4bool /*isUserFileName*/) >> 326 { 94 327 95 if (reset) { << 328 #ifdef G4VERBOSE 96 result &= Reset(); << 329 if ( fState.GetVerboseL4() ) 97 } << 330 fState.GetVerboseL4()->Message("read", "p2", p2Name); >> 331 #endif >> 332 >> 333 auto buffer = GetBuffer(fileName, p2Name, "ReadP2Impl"); >> 334 if ( ! buffer ) return kInvalidId; >> 335 >> 336 auto p2 = tools::rroot::TProfile2D_stream(*buffer); >> 337 delete buffer; >> 338 >> 339 if ( ! p2 ) { >> 340 G4ExceptionDescription description; >> 341 description >> 342 << " " >> 343 << "Streaming " << p2Name << " in file " << fileName << " failed."; >> 344 G4Exception("G4RootAnalysisReader::ReadP2Impl", >> 345 "Analysis_WR011", JustWarning, description); >> 346 return kInvalidId; >> 347 } >> 348 >> 349 auto id = fP2Manager->AddP2(p2Name, p2); >> 350 >> 351 #ifdef G4VERBOSE >> 352 if ( fState.GetVerboseL2() ) >> 353 fState.GetVerboseL2()->Message("read", "p2", p2Name, id > kInvalidId); >> 354 #endif >> 355 >> 356 return id; >> 357 } 98 358 99 fFileManager->CloseFiles(); << 359 //_____________________________________________________________________________ >> 360 G4int G4RootAnalysisReader::ReadNtupleImpl(const G4String& ntupleName, >> 361 const G4String& fileName, >> 362 const G4String& /*dirName*/, >> 363 G4bool isUserFileName) >> 364 { >> 365 #ifdef G4VERBOSE >> 366 if ( fState.GetVerboseL4() ) >> 367 fState.GetVerboseL4()->Message("read", "ntuple", ntupleName); >> 368 #endif >> 369 >> 370 // Ntuples are saved per thread >> 371 // but do not apply the thread suffix if fileName is provided explicitly >> 372 auto isPerThread = true; >> 373 if ( isUserFileName ) isPerThread = false; >> 374 >> 375 // Get or open a file >> 376 auto rfile = fFileManager->GetRFile(fileName, isPerThread); >> 377 if ( ! rfile ) { >> 378 if ( ! fFileManager->OpenRFile(fileName, isPerThread) ) return kInvalidId; >> 379 rfile = fFileManager->GetRFile(fileName, isPerThread); >> 380 } >> 381 >> 382 auto key = rfile->dir().find_key(ntupleName); >> 383 if ( ! key ) { >> 384 G4ExceptionDescription description; >> 385 description >> 386 << " " >> 387 << "Key " << ntupleName << " for Ntuple not found in file " << fileName; >> 388 G4Exception("G4RootAnalysisReader::ReadNtupleImpl()", >> 389 "Analysis_WR011", JustWarning, description); >> 390 return kInvalidId; >> 391 } 100 392 101 Message(kVL2, "close", "files", "", result); << 393 unsigned int size; >> 394 char* charBuffer = key->get_object_buffer(*rfile, size); >> 395 if ( ! charBuffer ) { >> 396 G4ExceptionDescription description; >> 397 description >> 398 << " " >> 399 << "Cannot get data buffer for Ntuple " << ntupleName << " in file " << fileName; >> 400 G4Exception("G4RootAnalysisReader::ReadNtupleImpl()", >> 401 "Analysis_WR021", JustWarning, description); >> 402 return kInvalidId; >> 403 } >> 404 >> 405 auto verbose = false; >> 406 auto buffer >> 407 = new tools::rroot::buffer(G4cout, rfile->byte_swap(), size, charBuffer, >> 408 key->key_length(), verbose); >> 409 buffer->set_map_objs(true); >> 410 >> 411 auto fac = new tools::rroot::fac(G4cout); >> 412 >> 413 auto tree = new tools::rroot::tree(*rfile, *fac); >> 414 if ( ! tree->stream(*buffer) ) { >> 415 G4ExceptionDescription description; >> 416 description >> 417 << " " >> 418 << "TTree streaming failed for Ntuple " << ntupleName << " in file " << fileName; >> 419 G4Exception("G4RootAnalysisReader::ReadNtupleImpl()", >> 420 "Analysis_WR021", JustWarning, description); >> 421 >> 422 delete buffer; >> 423 delete tree; >> 424 return kInvalidId; >> 425 } >> 426 >> 427 auto rntuple = new tools::rroot::ntuple(*tree); //use the flat ntuple API. >> 428 auto rntupleDescription = new G4TRNtupleDescription<tools::rroot::ntuple>(rntuple); >> 429 >> 430 auto id = fNtupleManager->SetNtuple(rntupleDescription); >> 431 >> 432 #ifdef G4VERBOSE >> 433 if ( fState.GetVerboseL2() ) >> 434 fState.GetVerboseL2()->Message("read", "ntuple", ntupleName, id > kInvalidId); >> 435 #endif 102 436 103 return result; << 437 return id; 104 } << 438 } 105 439