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