GSI Object Oriented Online Offline (Go4)  GO4-6.3.0
TGo4MbsFile.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 #include "TGo4MbsFile.h"
15 
16 #include <cstring>
17 #include <iosfwd>
18 #include <iostream>
19 #include <fstream>
20 
21 #include "TSystem.h"
22 #include "TROOT.h"
23 #include "TList.h"
24 #include "TObjString.h"
25 
26 #include "TGo4Log.h"
27 
28 #include "TGo4MbsFileParameter.h"
30 #include "TGo4EventEndException.h"
31 #include "TGo4FileSource.h"
32 #include "TGo4AnalysisImp.h"
33 
34 const char *TGo4MbsFile::fgcNOTAGFILE="GO4-NOLMDTAG";
35 const char *TGo4MbsFile::fgcLMDSUF=".lmd";
36 const char *TGo4MbsFile::fgcFILELISTSUF=".lml";
37 
39  TGo4MbsSource(),
40  fxTagFile(),
41  fxCurrentFile(),
42  fxCurrentTag(),
43  fxMultiFile(nullptr),
44  fbFileOpen(kFALSE),
45  fbShowInfo(kTRUE)
46 {
47  GO4TRACE((15,"TGo4MbsFile::TGo4MbsFile()",__LINE__, __FILE__));
48 }
49 
50 TGo4MbsFile::TGo4MbsFile(const char *name) :
52  fxTagFile(),
53  fxCurrentFile(),
54  fxCurrentTag(),
55  fxMultiFile(nullptr),
56  fbFileOpen(kFALSE),
57  fbShowInfo(kTRUE)
58 {
59  GO4TRACE((15,"TGo4MbsFile::TGo4MbsFile(const char *)",__LINE__, __FILE__));
60 
61  TGo4Log::Debug(" New Event Source MbsFile %s: ", GetName());
63 
64  AddFileName(name, nullptr, kTRUE);
65 
66  Open();
67 }
68 
71  fxTagFile(),
72  fxCurrentFile(),
73  fxCurrentTag(),
74  fxMultiFile(nullptr),
75  fbFileOpen(kFALSE),
76  fbShowInfo(kTRUE)
77 {
78  GO4TRACE((15,"TGo4MbsFile::TGo4MbsFile(TGo4MbsFileParameter*)",__LINE__, __FILE__));
79 
80  if(par) {
81  fxTagFile = par->GetTagName();
82 
83  AddFileName(GetName(), fxTagFile.Data(), par->NumMoreFiles() == 0);
84  for (Int_t n = 0; n < par->NumMoreFiles(); n++)
85  AddFileName(par->GetMoreName(n), nullptr, kFALSE);
86  }
87 
88  TGo4Log::Debug("New Event Source MbsFile %s", GetName());
89 
90  Open();
91 }
92 
94 {
95  GO4TRACE((15,"TGo4MbsFile::~TGo4MbsFile()",__LINE__, __FILE__));
96  Close();
97 
98  if(fxMultiFile) { delete fxMultiFile; fxMultiFile = nullptr; }
99 }
100 
101 void TGo4MbsFile::AddFileName(const char *name, const char *tagname, bool isonly)
102 {
103  if (!name || !*name) return;
104 
105  TString fname(name);
106 
107  bool read_multi = false;
108 
109  // evaluate wildcard input:
110  if(fname[0]=='@') { // old style: filelist name starts with @
111  // name indicates steering file
112  fname.Remove(0, 1);
113  read_multi = true;
114  } else if(fname.EndsWith(fgcFILELISTSUF)) { // new style: list mode list
115  read_multi = true;
116  } else if(fname.Contains("*") || fname.Contains("?")) {
117  // name indicates wildcard expression
118  TList *lst = TGo4FileSource::ProducesFilesList(fname.Data());
119 
120  if (!lst) {
122  SetErrMess(TString::Format("No lmd file with mask %s", GetName()).Data());
123  throw TGo4EventErrorException(this);
124  }
125 
126  if (!fxMultiFile) {
127  fxMultiFile = lst;
128  } else {
129  lst->SetOwner(kFALSE);
130  fxMultiFile->AddAll(lst);
131  delete lst;
132  }
133 
134  } else if (!isonly) {
135  // only if more file names are expected we will start extra list with files names
136 
137  if (!fxMultiFile) { fxMultiFile = new TList; fxMultiFile->SetOwner(kTRUE); }
138 
139  if (tagname && (strcmp(tagname,fgcNOTAGFILE) != 0)) {
140  fname += " ";
141  fname += tagname;
142  }
143 
144  fxMultiFile->Add(new TObjString(fname));
145  }
146 
148  // now treat different input modes:
149  if(read_multi) {
150  std::ifstream ff(fname.Data());
151  if(!ff) {
153  SetErrMess(TString::Format("Error opening multiple file:%s", fname.Data()).Data());
154  throw TGo4EventErrorException(this);
155  }
156 
157  if (!fxMultiFile) {
158  fxMultiFile = new TList;
159  fxMultiFile->SetOwner(kTRUE);
160  }
161 
162  char nextline[TGo4EventSource::fguTXTLEN];
163 
164  while (!ff.eof()) {
165  ff.getline(nextline, TGo4EventSource::fguTXTLEN, '\n');
166 
167  fxMultiFile->Add(new TObjString(nextline));
168  }
169  }
170 
171  if (isonly)
172  SetName(fname);
173  else
174  SetName("LmdFilesSelection");
175 }
176 
178 {
179  if (fbShowInfo) {
180  fbShowInfo = kFALSE;
181  TGo4Log::Info("Start file: %s tagfile:%s first:%lu last:%lu delta:%lu",GetCurrentFileName(),GetCurrentTagName(), fuStartEvent,fuStopEvent, fuEventInterval);
182  }
183 
184  GO4TRACE((12,"TGo4MbsFile::NextEvent()",__LINE__, __FILE__));
185  try{
186  Int_t skip = 0;
187  // test if we had reached the last event:
188  if(fuStopEvent != 0 && fuEventCounter >= fuStopEvent) {
190  } else {
191  if(fbFirstEvent) {
192  if(fuStartEvent>0) {
193  // we want to work with "real" event number for first event
194  skip = (Int_t) fuStartEvent-1;
195  if(skip) fuEventCounter++; // need to correct for init value of event counter below!
196  } else {
197  skip = 0;
198  }
199  fbFirstEvent = kFALSE;
200  } else {
201  skip = (Int_t) fuEventInterval;
202  }
203  void *evptr = &fxEvent; // some new compilers may warn if we directly dereference member variable in function argument
204  Int_t status = f_evt_get_tagnext(fxInputChannel, skip, (Int_t **) evptr);
205  if(skip)
206  fuEventCounter+=skip;
207  else
208  fuEventCounter++;
209  SetEventStatus(status);
210  }
211  if(GetEventStatus() != 0) {
212  char buffer[TGo4EventSource::fguTXTLEN];
213  f_evt_error(GetEventStatus(),buffer,1); // provide text message for later output
214  SetErrMess(TString::Format("%s file:%s", buffer, GetCurrentFileName()).Data());
215  }
216 
218  throw TGo4EventEndException(this);
219  else if (GetEventStatus() != 0)
220  throw TGo4EventErrorException(this);
221 
222  return GetEventStatus();
223 
224  } // try
225 
226  catch(TGo4EventEndException& ex) {
227  if(fxMultiFile) {
228  ex.Handle(); // display message
229  // catch here the end of file case only
230  // try to open next file in list:
231  TGo4Log::Info("End file: %s",GetCurrentFileName());
232 
233  while(NextFile() < 0);
234  //skip filenames with open error until a file
235  // in the list opens properly (retval == 0)
236  SetErrMess("");
237  NewFileAction();
238  throw TGo4EventErrorException(this,0);
239  // priority 0 means do not stop analysis
240  // we (mis-)use an error exception with no stop to
241  // skip the processing of the previous event in the
242  // subsequent analysis for a second time
243  // note that NextFile() throws an exception itself
244  // if list of files is at end
245  } else {
246  throw; // normal end of input for one file
247  }
248  }
249 }
250 
251 
253 {
254  GO4TRACE((12,"TGo4MbsFile::Close()",__LINE__, __FILE__));
255  if(!fbIsOpen) return -1;
256 
257  Int_t rev = GetCreateStatus();
258  // close connection/file
259  if(CloseFile() == GETEVT__SUCCESS) fbIsOpen = kFALSE;
260 
261  if(fxMultiFile) { delete fxMultiFile; fxMultiFile = nullptr; }
262 
263  return rev;
264 }
265 
267 {
268  GO4TRACE((12,"TGo4MbsFile::Open()",__LINE__, __FILE__));
269 
270  if(fbIsOpen) return -1;
271 
273  // now treat different input modes:
274  if(fxMultiFile) {
275 
276  while(NextFile()<0); // skip invalid filenames
277  // note that TGo4EventEndException will break this loop if no valid file in list
278  fbIsOpen = kTRUE;
279  NewFileAction(kFALSE);
280  } else {
281  if(NextFile() < 0) {
282  // only for single mode the
283  // error result of first NextFile()
284  // will indicate that open failed
285  fbIsOpen = kFALSE;
286  } else {
287  fbIsOpen = kTRUE;
288  TGo4Log::Info("TGo4MbsFile: Open file %s", GetCurrentFileName());
289  }
290  }
291 
292  return 0;
293 }
294 
295 
297 {
298  CloseFile();
299  fuEventCounter = 0;
300  // read next name from namesfile
301  if(fxMultiFile) {
302  TString nextline;
303  char nextfile[TGo4EventSource::fguTXTLEN];
304  char nexttag[TGo4EventSource::fguTXTLEN];
305  const char *command = nullptr;
306  const char *rem1 = nullptr;
307  const char *rem2 = nullptr;
308  Int_t convs = 0;
309  do {
310  //if(fxMultiFile->rdstate()==ios::eofbit)
311  if(!fxMultiFile || (fxMultiFile->GetSize() == 0)) {
312  // reached last filename, or read error?
314  SetErrMess("End of files list");
315  //throw TGo4EventErrorException(this,3);
316  throw TGo4EventEndException(this);
317  }
318 
319  TObject *obj = fxMultiFile->First();
320  nextline = obj->GetName();
321  fxMultiFile->Remove(fxMultiFile->FirstLink());
322  delete obj;
323 
324  // this indicates that we will show file info when first event will be extracted
325  fbShowInfo = kTRUE;
326 
327  rem1 = strstr(nextline.Data(), "!");
328  rem2 = strstr(nextline.Data(), "#");
329  command = strstr(nextline.Data(), "@");
330  if(command && !(rem1 && rem1 < command) && !(rem2 && rem2 < command)) {
331  // keycharacter indicates we want to execute a root macro
332  // treat the case that @command is commented out before!
333  command++; // skip @ letter
334  TGo4Analysis::Instance()->Message(1,"TGo4MbsFile list:%s-- executing command: %s ", GetName(), command);
335  //TGo4Log::Info("TGo4MbsFile list:%s-- executing command: %s ", GetName(), command);
336  gROOT->ProcessLineSync(command);
337  }
338  } while(nextline.IsNull() || rem1 || rem2 || command); // skip any comments and empty lines, and continue after macro execution
339  convs = sscanf(nextline.Data(),"%s %s %lu %lu %lu",nextfile,nexttag,
341  if(convs<2) {
342  // line contained not all parameters, reset remaining
343  fuStartEvent = 0;
344  fuStopEvent = 0;
345  fuEventInterval = 0;
347  }
348  fxCurrentFile = nextfile;
349  if(!strcmp(nexttag,"0") || !strcmp(nexttag,""))
350  fxCurrentTag = TGo4MbsFile::fgcNOTAGFILE; // no tagfile if no name
351  else
352  fxCurrentTag = nexttag;
353  } else {
354  //no multiple file: use default names
356  fxCurrentFile = GetName();
357  }
358 
359  try {
360  OpenFile();
361  return 0;
362  }// try
363 
364  catch(TGo4EventErrorException& ex)
365  {
366  if(fxMultiFile) {
367  // something went wrong opening next file, skip it
368  ex.Handle();
369  CloseFile();
370  return -1;
371  } else {
372  throw;
373  }
374 
375  }
376 }
377 
379 {
380  if(fbFileOpen) return -1;
381 
382  const char *tagfile = GetCurrentTagName();
383  if(!strcmp(tagfile,TGo4MbsFile::fgcNOTAGFILE)) {
384  tagfile = nullptr;
385  fxCurrentTag = "none"; // looks better in display message
386  }
387  void *headptr=&fxInfoHeader; // some new compilers may warn if we directly dereference member
388  Int_t status = f_evt_get_tagopen(fxInputChannel,
389  const_cast<char *>(tagfile),
390  const_cast<char *>(GetCurrentFileName()),
391  (Char_t**) headptr, 0);
392  SetCreateStatus(status);
394  char buffer[TGo4EventSource::fguTXTLEN];
395  f_evt_error(GetCreateStatus(), buffer, 1); // provide text message for later output
396  SetErrMess(TString::Format("%s file:%s", buffer, GetCurrentFileName()).Data());
397  fbFileOpen = kFALSE;
398  throw TGo4EventErrorException(this);
399  } else {
400  fbFileOpen = kTRUE;
401  fbFirstEvent = kTRUE;
402  TGo4Log::Debug(" Mbs File -- opened %s ", GetName());
403  }
404  return status;
405 }
406 
408 {
409  if(!fbFileOpen) return -1;
410  Int_t rev = f_evt_get_tagclose(fxInputChannel);
411  if(rev == GETEVT__SUCCESS) fbFileOpen = kFALSE;
412  return rev;
413 }
414 
415 Int_t TGo4MbsFile::NewFileAction(Bool_t dosave)
416 {
418  ana->SetNewInputFile(kTRUE);
420  TGo4Analysis::Instance()->Message(1,"TGo4MbsFile list:%s-- opening new file: %s ", GetName(), GetCurrentFileName());
421 
422  if(ana->IsAutoSaveFileChange()) {
423  TString fname = GetCurrentFileName();
424  fname.ReplaceAll(".lmd",4,"_ASF",4);
425  if(dosave) ana->AutoSave();
426  ana->ClearObjects("Histograms");
427  TString asfname = fname+".root";
428  std::cout << "Setting autosavefile to name " << asfname << std::endl;
429  ana->SetAutoSaveFile(asfname.Data());
430  if(dosave) ana->AutoSave();
431  }
432  return 0;
433 }
434 
435 const char *TGo4MbsFile::GetActiveName() const
436 {
437  return GetCurrentFileName();
438 }
static const char * fgcLMDSUF
Definition: TGo4MbsFile.h:64
#define GETEVT__SUCCESS
Definition: f_evt.h:131
const char * GetCurrentFileName() const
Definition: TGo4MbsFile.h:55
const char * GetTagName() const
Definition: TGo4MbsFile.h:51
s_evt_channel * fxInputChannel
Int_t NextFile()
Int_t GetCreateStatus() const
static void Info(const char *text,...) GO4_PRINTF_ARGS
Definition: TGo4Log.cxx:294
s_filhe * fxInfoHeader
#define GETEVT__NOFILE
Definition: f_evt.h:135
void SetCreateStatus(Int_t status)
TString fxTagFile
Definition: TGo4MbsFile.h:88
void SetAutoSaveFile(const char *filename=nullptr, Bool_t overwrite=kFALSE, Int_t compression=5)
Int_t CloseFile()
INTS4 f_evt_error(INTS4 l_error, CHARS *pc_dest, INTS4 l_out)
Definition: f_evt.c:1586
#define GETEVT__NOMORE
Definition: f_evt.h:134
const char * GetTagName() const
ULong_t fuEventCounter
ULong_t fuEventInterval
Bool_t IsAutoSaveFileChange() const
void SetNewInputFile(Bool_t on=kTRUE)
static const char * fgcNOTAGFILE
Definition: TGo4MbsFile.h:61
static void Debug(const char *text,...) GO4_PRINTF_ARGS
Definition: TGo4Log.cxx:281
INTS4 f_evt_get_tagnext(s_evt_channel *ps_chan, INTS4 l_skip, INTS4 **pl_event)
Definition: f_evt.c:2594
Int_t Close() override
void SetErrMess(const char *txt)
Int_t OpenFile()
TString fxCurrentTag
Definition: TGo4MbsFile.h:94
void Message(Int_t prio, const char *text,...)
Bool_t fbShowInfo
Definition: TGo4MbsFile.h:104
Bool_t fbFileOpen
Definition: TGo4MbsFile.h:101
s_ve10_1 * fxEvent
Bool_t ClearObjects(const char *name)
void SetInputFileName(const char *fname)
INTS4 f_evt_get_tagopen(s_evt_channel *ps_chan, CHARS *pc_tag, CHARS *pc_lmd, CHARS **ps_head, INTS4 l_prihe)
Definition: f_evt.c:2470
TString fxCurrentFile
Definition: TGo4MbsFile.h:91
const char * GetCurrentTagName() const
Definition: TGo4MbsFile.h:53
void AddFileName(const char *name, const char *tagname=nullptr, bool isonly=kFALSE)
Bool_t fbFirstEvent
Int_t NextEvent() override
void SetEventStatus(Int_t status)
#define GO4TRACE(X)
Definition: TGo4Log.h:25
static TList * ProducesFilesList(const char *mask)
Int_t Open() override
const char * GetActiveName() const override
ULong_t fuStartEvent
Int_t NewFileAction(Bool_t dosave=kTRUE)
ULong_t fuStopEvent
static TGo4Analysis * Instance()
INTS4 f_evt_get_tagclose(s_evt_channel *ps_chan)
Definition: f_evt.c:2801
static const char * fgcFILELISTSUF
Definition: TGo4MbsFile.h:67
Int_t GetEventStatus() const
#define GETEVT__FILE
Definition: f_evt.h:120
const char * GetMoreName(Int_t n) const
TList * fxMultiFile
Definition: TGo4MbsFile.h:98