ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4RootAnalysisReader.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4RootAnalysisReader.cc
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 
27 // Author: Ivana Hrivnacova, 09/04/2014 (ivana@ipno.in2p3.fr)
28 
29 #include "G4RootAnalysisReader.hh"
30 #include "G4RootRFileManager.hh"
31 #include "G4RootRNtupleManager.hh"
32 #include "G4AnalysisVerbose.hh"
33 #include "G4AnalysisUtilities.hh"
34 #include "G4Threading.hh"
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 
45 using namespace G4Analysis;
46 
49 
50 //_____________________________________________________________________________
52 {
53  if ( fgInstance == nullptr ) {
54  G4bool isMaster = ! G4Threading::IsWorkerThread();
55  fgInstance = new G4RootAnalysisReader(isMaster);
56  }
57 
58  return fgInstance;
59 }
60 
61 //_____________________________________________________________________________
63  : G4ToolsAnalysisReader("Root", isMaster),
64  fNtupleManager(nullptr),
65  fFileManager(nullptr)
66 {
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;
78 
79  // Create managers
82  // The managers will be deleted by the base class
83 
84  // Set managers to base class
87 }
88 
89 //_____________________________________________________________________________
91 {
92  if ( fState.GetIsMaster() ) fgMasterInstance = nullptr;
93  fgInstance = nullptr;
94 }
95 
96 //
97 // private methods
98 //
99 
100 //_____________________________________________________________________________
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 //_____________________________________________________________________________
145 {
146 // Reset histograms and ntuple
147 
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 //
162 
163 //_____________________________________________________________________________
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 }
199 
200 //_____________________________________________________________________________
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 }
241 
242 //_____________________________________________________________________________
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 }
283 
284 //_____________________________________________________________________________
286  const G4String& fileName,
287  const G4String& /*dirName*/,
288  G4bool /*isUserFileName*/)
289 {
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 }
320 
321 //_____________________________________________________________________________
323  const G4String& fileName,
324  const G4String& /*dirName*/,
325  G4bool /*isUserFileName*/)
326 {
327 
328 #ifdef G4VERBOSE
329  if ( fState.GetVerboseL4() )
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 }
358 
359 //_____________________________________________________________________________
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  }
392 
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
436 
437  return id;
438 }