Geant4  10.03.p03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4RootAnalysisReader.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // $Id: G4RootAnalysisReader.cc 74257 2013-10-02 14:24:55Z gcosmo $
27 
28 // Author: Ivana Hrivnacova, 09/04/2014 (ivana@ipno.in2p3.fr)
29 
30 #include "G4RootAnalysisReader.hh"
31 #include "G4RootRFileManager.hh"
32 #include "G4RootRNtupleManager.hh"
34 #include "G4AnalysisVerbose.hh"
35 #include "G4AnalysisUtilities.hh"
36 #include "G4Threading.hh"
37 
38 #include <tools/rroot/file>
39 #include <tools/rroot/streamers>
40 #include <tools/rroot/fac>
41 #include <tools/rroot/tree>
42 #include <tools/rroot/ntuple>
43 
44 #include <iostream>
45 #include <cstdio>
46 
47 using namespace G4Analysis;
48 
49 G4RootAnalysisReader* G4RootAnalysisReader::fgMasterInstance = nullptr;
50 G4ThreadLocal G4RootAnalysisReader* G4RootAnalysisReader::fgInstance = nullptr;
51 
52 //_____________________________________________________________________________
54 {
55  if ( fgInstance == nullptr ) {
56  G4bool isMaster = ! G4Threading::IsWorkerThread();
57  fgInstance = new G4RootAnalysisReader(isMaster);
58  }
59 
60  return fgInstance;
61 }
62 
63 //_____________________________________________________________________________
65  : G4ToolsAnalysisReader("Root", isMaster),
66  fNtupleManager(nullptr),
67  fFileManager(nullptr)
68 {
69  if ( ( isMaster && fgMasterInstance ) || ( fgInstance ) ) {
70  G4ExceptionDescription description;
71  description
72  << " "
73  << "G4RootAnalysisReader already exists."
74  << "Cannot create another instance.";
75  G4Exception("G4RootAnalysisReader::G4RootAnalysisReader()",
76  "Analysis_F001", FatalException, description);
77  }
78  if ( isMaster ) fgMasterInstance = this;
79  fgInstance = this;
80 
81  // Create managers
82  fNtupleManager = new G4RootRNtupleManager(fState);
83  fFileManager = new G4RootRFileManager(fState);
84  // The managers will be deleted by the base class
85 
86  // Set managers to base class
87  SetNtupleManager(fNtupleManager);
88  SetFileManager(fFileManager);
89 }
90 
91 //_____________________________________________________________________________
93 {
94  if ( fState.GetIsMaster() ) fgMasterInstance = nullptr;
95  fgInstance = nullptr;
96 }
97 
98 //
99 // private methods
100 //
101 
102 //_____________________________________________________________________________
103 tools::rroot::buffer* G4RootAnalysisReader::GetBuffer(
104  const G4String& fileName,
105  const G4String& objectName,
106  const G4String& inFunction)
107 {
108 // Get buffer for reading histogram or profile specified by objectNmae
109 // for a file specified by fileName;
110 // open the file if it was not yet open
111 
112  // Histograms and profiles are not saved per thread
113  G4bool isPerThread = false;
114 
115  // Get or open a file
116  auto rfile = fFileManager->GetRFile(fileName, isPerThread);
117  if ( ! rfile ) {
118  if ( ! fFileManager->OpenRFile(fileName, isPerThread) ) return nullptr;
119  rfile = fFileManager->GetRFile(fileName, isPerThread);
120  }
121 
122  auto key
123  = ( ! rfile ) ? nullptr : rfile->dir().find_key(objectName);
124 
125  unsigned int size;
126  //char* charBuffer
127  // = ( ! key ) ? 0 : key->get_object_buffer(size);
128  char* charBuffer = 0;
129  if ( key ) charBuffer = key->get_object_buffer(*rfile, size);
130 
131  if ( ! charBuffer ) {
132  G4ExceptionDescription description;
133  description
134  << " "
135  << "Cannot get " << objectName << " in file " << fileName;
136  G4Exception(inFunction, "Analysis_WR011", JustWarning, description);
137  return nullptr;
138  }
139 
140  auto verbose = false;
141  return new tools::rroot::buffer(G4cout, rfile->byte_swap(), size, charBuffer,
142  key->key_length(), verbose);
143 }
144 
145 //_____________________________________________________________________________
146 G4bool G4RootAnalysisReader::Reset()
147 {
148 // Reset histograms and ntuple
149 
150  auto finalResult = true;
151 
153  finalResult = finalResult && result;
154 
155  result = fNtupleManager->Reset();
156  finalResult = finalResult && result;
157 
158  return finalResult;
159 }
160 
161 //
162 // protected methods
163 //
164 
165 //_____________________________________________________________________________
167  const G4String& fileName,
168  G4bool /*isUserFileName*/)
169 {
170 #ifdef G4VERBOSE
171  if ( fState.GetVerboseL4() )
172  fState.GetVerboseL4()->Message("read", "h1", h1Name);
173 #endif
174 
175  auto buffer = GetBuffer(fileName, h1Name, "ReadH1Impl");
176  if ( ! buffer ) return kInvalidId;
177 
178  auto h1 = tools::rroot::TH1D_stream(*buffer);
179  delete buffer;
180 
181  if ( ! h1 ) {
182  G4ExceptionDescription description;
183  description
184  << " "
185  << "Streaming " << h1Name << " in file " << fileName << " failed.";
186  G4Exception("G4RootAnalysisReader::ReadH1Impl",
187  "Analysis_WR011", JustWarning, description);
188  return kInvalidId;
189  }
190 
191  auto id = fH1Manager->AddH1(h1Name, h1);
192 
193 #ifdef G4VERBOSE
194  if ( fState.GetVerboseL2() )
195  fState.GetVerboseL2()->Message("read", "h1", h1Name, id > kInvalidId);
196 #endif
197 
198  return id;
199 }
200 
201 //_____________________________________________________________________________
203  const G4String& fileName,
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 }
241 
242 //_____________________________________________________________________________
244  const G4String& fileName,
245  G4bool /*isUserFileName*/)
246 {
247 
248 #ifdef G4VERBOSE
249  if ( fState.GetVerboseL4() )
250  fState.GetVerboseL4()->Message("read", "h3", h3Name);
251 #endif
252 
253  auto buffer = GetBuffer(fileName, h3Name, "ReadH3Impl");
254  if ( ! buffer ) return kInvalidId;
255 
256  auto h3 = tools::rroot::TH3D_stream(*buffer);
257  delete buffer;
258 
259  if ( ! h3 ) {
260  G4ExceptionDescription description;
261  description
262  << " "
263  << "Streaming " << h3Name << " in file " << fileName << " failed.";
264  G4Exception("G4RootAnalysisReader::ReadH3Impl",
265  "Analysis_WR011", JustWarning, description);
266  return kInvalidId;
267  }
268 
269  auto id = fH3Manager->AddH3(h3Name, h3);
270 
271 #ifdef G4VERBOSE
272  if ( fState.GetVerboseL2() )
273  fState.GetVerboseL2()->Message("read", "h3", h3Name, id > kInvalidId);
274 #endif
275 
276  return id;
277 /*
278  // not yet available
279  return kInvalidId;
280 */
281 }
282 
283 //_____________________________________________________________________________
285  const G4String& fileName,
286  G4bool /*isUserFileName*/)
287 {
288 #ifdef G4VERBOSE
289  if ( fState.GetVerboseL4() )
290  fState.GetVerboseL4()->Message("read", "p1", p1Name);
291 #endif
292 
293  auto buffer = GetBuffer(fileName, p1Name, "ReadP1Impl");
294  if ( ! buffer ) return kInvalidId;
295 
296  auto p1 = tools::rroot::TProfile_stream(*buffer);
297  delete buffer;
298 
299  if ( ! p1 ) {
300  G4ExceptionDescription description;
301  description
302  << " "
303  << "Streaming " << p1Name << " in file " << fileName << " failed.";
304  G4Exception("G4RootAnalysisReader::ReadP1Impl",
305  "Analysis_WR011", JustWarning, description);
306  return kInvalidId;
307  }
308 
309  auto id = fP1Manager->AddP1(p1Name, p1);
310 
311 #ifdef G4VERBOSE
312  if ( fState.GetVerboseL2() )
313  fState.GetVerboseL2()->Message("read", "p1", p1Name, id > kInvalidId);
314 #endif
315 
316  return id;
317 }
318 
319 //_____________________________________________________________________________
321  const G4String& fileName,
322  G4bool /*isUserFileName*/)
323 {
324 
325 #ifdef G4VERBOSE
326  if ( fState.GetVerboseL4() )
327  fState.GetVerboseL4()->Message("read", "p2", p2Name);
328 #endif
329 
330  auto buffer = GetBuffer(fileName, p2Name, "ReadP2Impl");
331  if ( ! buffer ) return kInvalidId;
332 
333  auto p2 = tools::rroot::TProfile2D_stream(*buffer);
334  delete buffer;
335 
336  if ( ! p2 ) {
337  G4ExceptionDescription description;
338  description
339  << " "
340  << "Streaming " << p2Name << " in file " << fileName << " failed.";
341  G4Exception("G4RootAnalysisReader::ReadP2Impl",
342  "Analysis_WR011", JustWarning, description);
343  return kInvalidId;
344  }
345 
346  auto id = fP2Manager->AddP2(p2Name, p2);
347 
348 #ifdef G4VERBOSE
349  if ( fState.GetVerboseL2() )
350  fState.GetVerboseL2()->Message("read", "p2", p2Name, id > kInvalidId);
351 #endif
352 
353  return id;
354 }
355 
356 //_____________________________________________________________________________
358  const G4String& fileName,
359  G4bool isUserFileName)
360 {
361 #ifdef G4VERBOSE
362  if ( fState.GetVerboseL4() )
363  fState.GetVerboseL4()->Message("read", "ntuple", ntupleName);
364 #endif
365 
366  // Ntuples are saved per thread
367  // but do not apply the thread suffix if fileName is provided explicitly
368  auto isPerThread = true;
369  if ( isUserFileName ) isPerThread = false;
370 
371  // Get or open a file
372  auto rfile = fFileManager->GetRFile(fileName, isPerThread);
373  if ( ! rfile ) {
374  if ( ! fFileManager->OpenRFile(fileName, isPerThread) ) return kInvalidId;
375  rfile = fFileManager->GetRFile(fileName, isPerThread);
376  }
377 
378  auto key = rfile->dir().find_key(ntupleName);
379  if ( ! key ) {
380  G4ExceptionDescription description;
381  description
382  << " "
383  << "Key " << ntupleName << " for Ntuple not found in file " << fileName;
384  G4Exception("G4RootAnalysisReader::ReadNtupleImpl()",
385  "Analysis_WR011", JustWarning, description);
386  return kInvalidId;
387  }
388 
389  unsigned int size;
390  char* charBuffer = key->get_object_buffer(*rfile, size);
391  if ( ! charBuffer ) {
392  G4ExceptionDescription description;
393  description
394  << " "
395  << "Cannot get data buffer for Ntuple " << ntupleName << " in file " << fileName;
396  G4Exception("G4RootAnalysisReader::ReadNtupleImpl()",
397  "Analysis_WR021", JustWarning, description);
398  return kInvalidId;
399  }
400 
401  auto verbose = false;
402  auto buffer
403  = new tools::rroot::buffer(G4cout, rfile->byte_swap(), size, charBuffer,
404  key->key_length(), verbose);
405  auto fac = new tools::rroot::fac(G4cout);
406 
407  auto tree = new tools::rroot::tree(*rfile, *fac);
408  if ( ! tree->stream(*buffer) ) {
409  G4ExceptionDescription description;
410  description
411  << " "
412  << "TTree streaming failed for Ntuple " << ntupleName << " in file " << fileName;
413  G4Exception("G4RootAnalysisReader::ReadNtupleImpl()",
414  "Analysis_WR021", JustWarning, description);
415 
416  delete buffer;
417  delete tree;
418  return kInvalidId;
419  }
420 
421  auto rntuple
422  = new tools::rroot::ntuple(*tree); //use the flat ntuple API.
423  auto rntupleDescription
424  = new G4RootRNtupleDescription(rntuple, buffer, fac, tree);
425 
426  auto id = fNtupleManager->SetNtuple(rntupleDescription);
427 
428 #ifdef G4VERBOSE
429  if ( fState.GetVerboseL2() )
430  fState.GetVerboseL2()->Message("read", "ntuple", ntupleName, id > kInvalidId);
431 #endif
432 
433  return id;
434 }
G4double G4ParticleHPJENDLHEData::G4double result
void Message(const G4String &action, const G4String &object, const G4String &objectName, G4bool success=true) const
G4int AddH3(const G4String &name, tools::histo::h3d *h3d)
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
G4P1ToolsManager * fP1Manager
G4H1ToolsManager * fH1Manager
#define buffer
Definition: xmlparse.cc:628
virtual G4int ReadNtupleImpl(const G4String &ntupleName, const G4String &fileName, G4bool isUserFileName) final
#define G4ThreadLocal
Definition: tls.hh:89
G4AnalysisManagerState fState
int G4int
Definition: G4Types.hh:78
virtual G4int ReadH3Impl(const G4String &h3Name, const G4String &fileName, G4bool isUserFileName) final
G4H3ToolsManager * fH3Manager
G4int AddP2(const G4String &name, tools::histo::p2d *p2d)
const G4AnalysisVerbose * GetVerboseL2() const
G4int SetNtuple(G4RootRNtupleDescription *rntupleDescription)
virtual G4bool OpenRFile(const G4String &fileName, G4bool isPerThread)
G4GLOB_DLL std::ostream G4cout
tuple tree
Definition: gammaraytel.py:4
const G4AnalysisVerbose * GetVerboseL4() const
G4H2ToolsManager * fH2Manager
virtual G4int ReadH2Impl(const G4String &h2Name, const G4String &fileName, G4bool isUserFileName) final
bool G4bool
Definition: G4Types.hh:79
tools::rroot::file * GetRFile(const G4String &fileName, G4bool isPerThread) const
void SetNtupleManager(G4VRNtupleManager *ntupleManager)
virtual G4int ReadH1Impl(const G4String &h1Name, const G4String &fileName, G4bool isUserFileName) final
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4P2ToolsManager * fP2Manager
G4bool IsWorkerThread()
Definition: G4Threading.cc:145
G4int AddP1(const G4String &name, tools::histo::p1d *p1d)
static G4RootAnalysisReader * Instance()
G4int AddH2(const G4String &name, tools::histo::h2d *h2d)
G4int AddH1(const G4String &name, tools::histo::h1d *h1d)
virtual G4int ReadP1Impl(const G4String &p1Name, const G4String &fileName, G4bool isUserFileName) final
static const G4double fac
G4RootAnalysisReader(G4bool isMaster=true)
virtual G4int ReadP2Impl(const G4String &p2Name, const G4String &fileName, G4bool isUserFileName) final
const G4int kInvalidId
void SetFileManager(G4BaseFileManager *fileManager)