GSI Object Oriented Online Offline (Go4)  GO4-6.3.0
TGo4HDF5Source.cxx
Go to the documentation of this file.
1 // $Id$
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 
15 
16 
17 #include "TGo4HDF5Source.h"
18 
19 #include "TKey.h"
20 #include "TFile.h"
21 #include "TTree.h"
22 #include "TList.h"
23 #include "TSystem.h"
24 #include "TObjString.h"
25 #include "TRegexp.h"
26 #include "TDataMember.h"
27 
28 #include "TGo4Log.h"
30 #include "TGo4EventElement.h"
32 // get static name constants from here
33 #include "TGo4HDF5Store.h"
34 
35 
36 
37 TGo4HDF5Source::TGo4HDF5Source(const char *name) :
38  TGo4EventSource(name), TGo4HDF5Adapter(), fxReadBuffer(nullptr), fiReadOffset(0), fxFilesNames(nullptr)
39 {
40  fxFilesNames = ProducesFilesList(GetName());
41 
42  if (!OpenNextFile())
43  ThrowError(66,0, TString::Format("!!! ERROR: Cannot open source %s!!!", GetName()).Data());
44 }
45 
47  TGo4EventSource(par->GetName()), TGo4HDF5Adapter(), fxReadBuffer(nullptr), fiReadOffset(0), fxFilesNames(nullptr)
48 {
49  // TODO: all file regexp magic into base class for all eventsources
50  fxFilesNames = ProducesFilesList(GetName());
51 
52  if (!OpenNextFile())
53  ThrowError(66,0, TString::Format("!!! ERROR: Cannot open source %s!!!", GetName()).Data());
54 }
55 
56 
58  TGo4EventSource("Go4HDF5Source"),TGo4HDF5Adapter(), fxReadBuffer(nullptr), fiReadOffset(0), fxFilesNames(nullptr)
59 {
60  // for streamer, do not open here!
61 }
62 
64 {
66 
67  if (fxFilesNames) {
68  delete fxFilesNames;
69  fxFilesNames = nullptr;
70  }
71 }
72 
73 TList *TGo4HDF5Source::ProducesFilesList(const char *mask)
74 {
75  if (!mask || (strlen(mask) == 0)) return nullptr;
76 
77  TString dirname, basename(mask);
78 
79  if (!basename.MaybeWildcard()) {
80 
81  // add default suffix
82  if(!strstr(basename.Data(),TGo4HDF5Adapter::fgcFILESUF))
83  basename += TGo4HDF5Adapter::fgcFILESUF;
84 
85  TList *lst = new TList();
86  lst->SetOwner(kTRUE);
87  lst->Add(new TObjString(basename));
88  return lst;
89  }
90 
91  Bool_t withdir = kFALSE;
92  Int_t slash = basename.Last('/');
93 
94 #ifdef _MSC_VER
95  if (slash < 0) slash = basename.Last('\\');
96 #endif
97 
98  if (slash >= 0) {
99  dirname = basename(0, slash);
100  basename.Remove(0, slash+1);
101  withdir = kTRUE;
102  } else {
103  dirname = gSystem->WorkingDirectory();
104  }
105 
106  void *dir = gSystem->OpenDirectory(gSystem->ExpandPathName(dirname.Data()));
107 
108  if (!dir) return nullptr;
109 
110  TList *lst = nullptr;
111 
112  TRegexp re(basename, kTRUE);
113  while (const char *file = gSystem->GetDirEntry(dir)) {
114  if (!strcmp(file,".") || !strcmp(file,"..")) continue;
115  TString s = file;
116  if ((basename != s) && (s.Index(re) == kNPOS)) continue;
117  if (!lst) {
118  lst = new TList;
119  lst->SetOwner(kTRUE);
120  }
121  if (withdir)
122  lst->Add(new TObjString(dirname + "/" + file));
123  else
124  lst->Add(new TObjString(file));
125  }
126  gSystem->FreeDirectory(dir);
127 
128  if (lst) lst->Sort();
129 
130  return lst;
131 }
132 
134 {
136 
137  if (!fxFilesNames || (fxFilesNames->GetSize() == 0)) return kFALSE;
138 
139  TObject *obj = fxFilesNames->First();
140  fxCurrentFileName = obj->GetName();
141  fxFilesNames->Remove(fxFilesNames->FirstLink());
142  delete obj;
143 
144  OpenFile(fxCurrentFileName.Data());
145  return kTRUE;
146 }
147 
148 
150 {
151  try {
152  CloseFile();
153  TGo4Log::Info("TGo4HDF5Source: Closed file %s", fxCurrentFileName.Data());
154  fxCurrentFileName = "";
155  return kTRUE;
156  } catch (H5::Exception &ex) {
157  TString msg = TString::Format("Close File %s with HDF5 exception in %s : %s\n", fxCurrentFileName.Data(),
158  ex.getCFuncName(), ex.getCDetailMsg());
159  TGo4Log::Error("TGo4HDF5Source: %s", msg.Data());
160  SetErrMess(msg.Data());
161  throw TGo4EventSourceException(this);
162  }
163 }
164 
165 void TGo4HDF5Source::OpenFile(const char *fname)
166 {
167  TString buffer(fname);
168  if (!strstr(buffer.Data(), TGo4HDF5Adapter::fgcFILESUF))
169  buffer.Append(TGo4HDF5Adapter::fgcFILESUF);
170 
171  try {
172  CloseFile();
173  fxFile = new H5::H5File(buffer.Data(), H5F_ACC_RDONLY);
174  TGo4Log::Info("TGo4HDF5Source %s: Open file %s for reading", GetName(), buffer.Data());
175  } catch (H5::Exception &ex) {
176  TString msg = TString::Format("OpenFile with HDF5 exception in %s : %s\n", ex.getCFuncName(), ex.getCDetailMsg());
177  TGo4Log::Error("TGo4HDF5Source: %s", msg.Data());
178  SetErrMess(msg.Data());
179  throw TGo4EventSourceException(this);
180  }
181 }
182 
184 {
185  // TODO: all hdf5 file and dataset treatment in adapter class common to source and store
186  if (fbDataSetExists)
187  return;
188  if (!event || !fxFile)
189  return;
190 
191  try {
192 
193  BuildDataType(event);
195  fbDataSetExists = kTRUE;
196  }
197 
198  catch (H5::Exception &ex) {
199  TString msg =
200  TString::Format("BuildDataSet with HDF5 exception in %s : %s\n", ex.getCFuncName(), ex.getCDetailMsg());
201  TGo4Log::Error("TGo4HDF5Source: %s", msg.Data());
202  SetErrMess(msg.Data());
203  throw TGo4EventSourceException(this);
204  }
205 }
206 
207 
209 {
210  delete fxReadBuffer;
212 }
213 
215 {
216  if (!dest)
217  ThrowError(0, 22, "!!! ERROR BuildEvent: no destination event!!!");
218 
219  fxEvent = dest; // address of next event into event pointer
220  BuildDataSet(dest);
221 
222  try {
223 
224 #ifdef GO4HDF5_DEBUG
225  printf("TGo4HDF5Source: fxEvent=0x%lx\n", (unsigned long) fxEvent);
226  printf("TGo4HDF5Source: Eventname:%s\n", fxEvent->GetName());
227  printf("TGo4HDF5Source: is valid:%d\n", fxEvent->IsValid());
228  printf("Go4 event has eventsource pointer 0x%lx \n",(long) fxEvent->GetEventSource());
229  printf("TGo4HDF5Source: Event printout:\n");
230  fxEvent->PrintEvent();
231  printf("\n");
232 #endif
233 
234  //fxHandle->SetObjectPointer(dest); // do it here to account dynamic changes in structure
236 
237 #ifdef GO4HDF5_DEBUG
238  printf("Go4 event has eventsource pointer 0x%lx \n",(long) fxEvent->GetEventSource());
239  printf("Go4 event has identifier 0x%lx \n",(long) fxEvent->getId());
240 #endif
241 
242  return kTRUE;
243  } catch (H5::Exception &ex) {
244  TString msg =
245  TString::Format("BuildEvent() with HDF5 exception in %s : %s\n", ex.getCFuncName(), ex.getCDetailMsg());
246  TGo4Log::Error("TGo4HDF5Source: %s", msg.Data());
247  SetErrMess(msg.Data());
248  throw TGo4EventSourceException(this);
249  }
250 }
virtual void BuildReadDataset(H5::H5File *file, TGo4HDF5Source *parent)
static const char * fgcFILESUF
Bool_t BuildEvent(TGo4EventElement *dest) override
H5::H5File * fxFile
void OpenFile(const char *fname) override
static void Info(const char *text,...) GO4_PRINTF_ARGS
Definition: TGo4Log.cxx:294
TString fxCurrentFileName
void BuildDataSet(TGo4EventElement *event) override
void DeleteDataSet() override
void ThrowError(Int_t creastat, Int_t errstat, const char *message,...)
Bool_t CloseCurrentFile()
void SetErrMess(const char *txt)
TList * fxFilesNames
virtual void Read(hsize_t sequencenum, H5::H5File *file)
TGo4EventElement * fxEvent
virtual void DeleteDataSet()
virtual ~TGo4HDF5Source()
static TList * ProducesFilesList(const char *mask)
static void Error(const char *text,...) GO4_PRINTF_ARGS
Definition: TGo4Log.cxx:320
void BuildDataType(TGo4EventElement *event, TGo4HDF5DataHandle *parent=nullptr, Int_t index=0)
Char_t * fxReadBuffer
virtual void CloseFile()
string msg
Definition: go4init.py:11
TGo4HDF5DataHandle * fxHandle