StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StTreeMaker.cxx
1 
3 // //
4 // StTreeMaker class, Star IO //
5 // //
7 #include <Stiostream.h>
8 #include "TError.h"
9 #include "St_DataSetIter.h"
10 #include "StTreeMaker.h"
11 #include "StObject.h"
12 TableImpl(dst_bfc_status);
13 
14 ClassImp(StTreeMaker)
15 static void RuncoHist(StTree *tree);
16 
17 
18 //_____________________________________________________________________________
19 StTreeMaker::StTreeMaker(const char *name, const char *ioFile,const char *treeName )
20 :StIOInterFace(name,"0")
21 {
22  fFile = ioFile; fIOMode="0";fTree=0;fFinished=0;
23  fBfcStatus = new St_dst_bfc_status("BfcStatus",100);
24  AddConst(fBfcStatus);
25  fTreeName = treeName;
26  if (! fTreeName ) {
27  TDataSet *parent = GetParent();
28  if (parent) {
29  StIOInterFace *grandparent = (StIOInterFace *) parent->GetParent();
30  if (grandparent) fTreeName = grandparent->GetTreeName();
31  }
32  }
33  if ( !fTreeName ) {
34  Warning("StTreeMaker", "%s default treeName == bfcTree is used",name);
35  fTreeName = "bfcTree";
36  }
37 }
38 //_____________________________________________________________________________
39 StTreeMaker::~StTreeMaker(){
40 }
41 //_____________________________________________________________________________
42 Int_t StTreeMaker::Open(const char*)
43 {
44  int i;
45 
46  assert(strchr("rwu",fIOMode[0]));
47  if(fTree) return 0;
48 
49  if (fTreeName.IsNull()) SetTreeName();
50 
51  if (GetDebug())
52  printf("<%s(%s)::Init> TreeName = %s\n",ClassName(),GetName(),GetTreeName());
53 
54 
55  if (fIOMode[0]=='r') { //Read mode
56 
57 // ReadReadReadReadReadReadReadReadReadReadReadRead
58 
59 
60  if (!fTree) {//Make tree
61  class TFilePtr {
62  private:
63  TFile *fFile;
64  public:
65  TFilePtr(TFile *f): fFile(f){;}
66  ~TFilePtr(){ delete fFile;};
67  operator TFile *(){ return fFile; }
68  Bool_t IsZombie() const { return fFile?fFile->IsZombie():kTRUE;}
69  };
70  TFilePtr tf = TFile::Open(fFile,"read","BFC StTree file");
71  if (tf.IsZombie()) {
72  Error("Init","Wrong input file %s\n",(const char*)fFile);
73  return kStErr;
74  }
75 
76 
77  fTree = StTree::GetTree(tf,GetTreeName()); assert(fTree);
78  fTree->SetIOMode("0");
79  if (GetDebug())
80  printf("<%s(%s)::Init> FOUND Tree %s in file %s\n",
81  ClassName(),GetName(),
82  fTree->GetName(),fFile.Data());
83 
84 // 1st branch must be mentioned in fFile
85  TString firstBr(fFile);
86  i = firstBr.Last('.'); assert(i>0);
87  firstBr.Replace(i,999,"");
88  i = firstBr.Last('.'); assert(i>0);
89  firstBr.Replace(0,i+1,"");
90 
91  St_DataSet *fst = fTree->Find(firstBr);
92  if (!fst) {//not found, add "Branch" to name
93  firstBr+="Branch";
94  fst = fTree->Find(firstBr);}
95  if (fst) {
96  ((StBranch*)fst)->SetIOMode("r");
97  fst->Shunt(0); fTree->AddFirst(fst);
98  printf("<%s(%s)::Init> Branch %s is MAIN in tree\n",ClassName(),GetName(),fst->GetName());
99  }
100  }
101 
102 //
103 // Several default branches
104 // SetBranch("histBranch" ,0,"r","const");
105 // SetBranch("runcoBranch",0,"r","const");
106 
107 //
108 
109  UpdateTree(0);
110  fTree->SetFile(fFile,"r");
111  fTree->SetUKey(0);
112  AddData(fTree);
113 // Register for outer world
114  SetOutput(fTree);
115 // fTree->SetFile(fFile,"r");
116 
117  } else { //Write mode
118 
119 // WriteWriteWriteWriteWriteWriteWriteWriteWriteWrite
120 
121  TString BaseName,FileName;
122 
123 // Try to get it from Read StTreeMaker
124  fTree = 0;
125  if (fIOMode[0]=='u') fTree = (StTree*)GetDataSet(GetTreeName());
126  if (fTree) { // Fantastic, we found it!!!
127 
128  StMaker *mk = GetMaker(fTree); assert(mk);
129  if (GetDebug())
130  printf("<%s(%s)::Init> FOUND Tree %s.%s\n",
131  ClassName(),GetName(),
132  mk->GetName(),fTree->GetName());
133 
134  } else { // Create new tree
135 
136  fTree = new StTree(GetTreeName());
137 
138  }//end of new tree
139 
140 
141  UpdateTree(0);
142  fTree->SetFile(fFile,"w");
143  fTree->SetUKey(0);
144  fTree->Close("keep");
145  }
146 // Treat special branches
147  RuncoHist(fTree);
148 
149  return 0;
150 }
151 //_____________________________________________________________________________
152 Int_t StTreeMaker::Init()
153 {
154  return Open();
155 }
156 //_____________________________________________________________________________
157 Int_t StTreeMaker::Skip(int nskip)
158 {
159  if(!fTree) return 0;
160  return fTree->Skip(nskip);
161 }
162 
163 //_____________________________________________________________________________
165 
166  fNIO++;
167  if (fIOMode[0]=='r') { //Read mode
168  int iret=0,ntry=13;
169  while(1999) {
170  iret = MakeRead();
171  if (iret!=kStErr && ntry--) break;
172  Warning("Make","%d *** ReadError ***\n",ntry);
173  }
174  return iret;
175 
176  } else { //Write mode
177 
178  return MakeWrite();
179 
180  }
181 }
182 //_____________________________________________________________________________
183 Int_t StTreeMaker::MakeRead(const StUKey &RunEvent){
184 
185  TDataSet *xrefMain[2];
186  int iret;
187  xrefMain[0] = StXRefManager::GetMain();
188 
189 
190  if (!RunEvent.IsNull()) iret = fTree->ReadEvent(RunEvent);
191  else iret = fTree->NextEvent( );
192 
193  StEvtHddr *hddr = GetEvtHddr();
194  if (Debug()) hddr->Print("");
195  if (iret) return iret;
196  St_DataSetIter nextBr(fTree);
197  StBranch *br ;
198  while ((br = (StBranch*)nextBr())){
199  SetOutput(br);
200  TString tsBr(br->GetName());
201  if (tsBr.Contains("Branch")) {
202  TString tsName = tsBr;
203  tsName.ReplaceAll("Branch","");
204  if (!br->Find(tsName)) SetOutput(tsName,br);
205  }
206  int lv=1; if (strncmp("runco",br->GetName(),5)==0) lv = 2;
207  SetOutputAll(br,lv);
208 // copy StEVTHddr (RunEvent)
209  if (!hddr) continue;
210  StEvtHddr *runevt = (StEvtHddr*)br->FindByName("RunEvent");
211  if (!runevt) continue;
212  *hddr = *runevt;
213 //
214  }
215  xrefMain[1] = StXRefManager::GetMain();
216 // New XREF main object?
217  if (xrefMain[1] && xrefMain[1]!=xrefMain[0] && xrefMain[1]->GetParent()==0 )
218  AddData(xrefMain[1]);
219  return iret;
220 }
221 //_____________________________________________________________________________
222 Int_t StTreeMaker::MakeWrite()
223 {
224 
225 // Fill branches
226  MakeBfcStatus();
227  if (!GetFailedMaker()) UpdateTree(1);
228  UpdateHddr();
229 
230 // Write StTree
231  Int_t k1 = GetRunNumber();
232  Int_t k2 = GetEventNumber();
233  if (k1 <= 0 || k2 <= 0) { k1 = GetNumber(); k2=0; }
234  StUKey ukey(k1,k2);
235  fTree->WriteEvent(ukey);
236  fTree->Clear();
237  return 0;
238 }
239 //_____________________________________________________________________________
240 Int_t StTreeMaker::MakeBfcStatus()
241 {
242  fBfcStatus->SetNRows(0);
243  int nrows = 0;
244  TDataSetIter nextMk(GetParentChain(),999);
245  TDataSet *ds = 0;
246  EDataSetPass kont=kContinue;
247  const char *name=0;
248  while ((ds = nextMk(kont)))
249  {
250  name = ds->GetName();
251  kont = kContinue;
252  if (strcmp(".make",name)==0) continue;
253  kont = kPrune;
254  if (name[0]=='.') continue;
255  kont = kContinue;
256  if (!ds->InheritsFrom(StMaker::Class())) continue;
257  int ret = ((StMaker*)ds)->GetMakeReturn();
258  // if (!ret) continue;
259  fBfcStatus->SetNRows(++nrows);
260  char * mkName = (*fBfcStatus)[nrows-1].maker_name;
261  mkName[0]=0; strncat(mkName,name,11);
262  (*fBfcStatus)[nrows-1].status = ret;
263  }
264 
265  return 0;
266 }
267 //_____________________________________________________________________________
268 void StTreeMaker::UpdateHddr()
269 {
270 // Fill branches by Run/Event info
271 
272  StBranch *br;
273  Option_t *opt=0;
274  St_DataSet *hd = GetEvtHddr();
275  StMaker *failmk = GetFailedMaker();
276  TString ts;
277  if (failmk ) {
278  ts = "discarded by ";
279  ts += failmk->ClassName();
280  ts += "::";
281  ts += failmk->GetName();
282  hd->SetTitle(ts);
283  }
284 
285  St_DataSetIter nextBr(fTree);
286 
287  while ((br = (StBranch *)nextBr())) { //Looop over branches
288  if ((opt = br->GetOption()) && strstr(opt,"CONST")) continue;
289  if (!failmk && !br->First()) continue;
290  St_DataSet *ds = br;
291  if (ds->First() && ds->First() == ds->Last()) ds = ds->First();
292  if (ds->Find("RunEvent")) continue;
293  St_DataSet *hdd = (St_DataSet*)hd->Clone();
294  hdd->SetName ("RunEvent");
295  hdd->SetTitle(ts);
296  ds->AddFirst(hdd);
297  if (fBfcStatus->GetNRows()) br->Add(fBfcStatus);
298  }
299 }
300 
301 //_____________________________________________________________________________
302 void StTreeMaker::UpdateTree(Int_t flag)
303 {
304 // Fill branches
305 
306  StBranch *br;
307  const char* logs;int nlog,isSetBr;
308  St_DataSet *upd,*updList,*dat,*ds;
309  const char *cc;
310 
311  TString updName,updTitl,updFile,updMode,updOpt,tlog;
312 
313  updList= Find(".branches");
314  if (!updList) return;
315  St_DataSetIter updNext(updList);
316  while ((upd=updNext())) {//loop updates
317  updTitl = upd->GetTitle();
318  updName = upd->GetName();
319  updFile = ""; updMode = ""; updOpt = "";
320  isSetBr = (updTitl.Index("SetBranch:")==0);
321  if (isSetBr && flag!=0) continue;
322 
323  if (isSetBr) {//SetBranch block
324  cc = strstr(updTitl,"file=");
325  if (cc) updFile.Replace(0,0,cc+5,strcspn(cc+5," "));
326  cc = strstr(updTitl,"mode=");
327  if (cc) updMode.Replace(0,0,cc+5,strcspn(cc+5," "));
328  cc = strstr(updTitl,"opt=");
329  if (cc) updOpt.Replace (0,0,cc+4,strcspn(cc+4," "));
330 
331  if (!updFile.IsNull()) delete upd; //delete SetBranch with concrete filename
332  } //endif SetBranch block*
333 
334  if (updName[0]=='*') { //Wild Card
335  if (!updMode.IsNull() || !updFile.IsNull()) fTree->SetFile(updFile,updMode,1);
336  continue;}
337 
338  br = (StBranch*)fTree->Find(updName);
339  if (!br) {br = new StBranch(updName,fTree);br->SetIOMode(fIOMode);}
340  if (!updMode.IsNull() || !updFile.IsNull()) br->SetFile(updFile,updMode);
341  if (!updOpt.IsNull()) br->SetOption((const char*)updOpt);
342 
343  if (flag==0) continue;
344 
345  logs = (const char*)updTitl;nlog=0;
346  while(1999) //loop over log names
347  {
348  logs += nlog + strspn(logs+nlog," "); nlog = strcspn(logs," ");if(!nlog) break;
349  tlog.Replace(0,999,logs,nlog);
350  dat = GetDataSet(tlog); if (!dat) continue;
351  if (dat->InheritsFrom(StMaker::Class())) dat = dat->Find(".data");
352  if (!dat) continue;
353  if (*dat->GetName()!='.' && !dat->InheritsFrom(StBranch::Class()))
354  {
355  br->Add(dat);
356  } else {
357  St_DataSetIter nextDs(dat);
358  while((ds = nextDs())) br->Add(ds);
359  }//end of datasets
360  }//end of log names
361 
362  }//end of updates
363 
364 }
365 //_____________________________________________________________________________
367 {
368  if (fFinished) return 0;
369  fFinished = 1999;
370  if (!fTree) return 0;
371  if (fIOMode[0]!='r') { //write mode
372  St_DataSetIter nextBr(fTree);
373  StBranch *br;
374  fTree->Clear();
375  while ((br = (StBranch*)nextBr())) {
376  if (strncmp("hist" ,br->GetName(),4)
377  && strncmp("runco",br->GetName(),5)) continue;
378  FillHistBranch(br);
379  }
380  fTree->WriteEvent((ULong_t)(-2));
381  fTree->Clear();
382  }
383  Close();
385  return 0;
386 }
387 //_____________________________________________________________________________
388 Int_t StTreeMaker::Save()
389 {
390  St_DataSetIter nextBr(fTree);
391  StBranch *br,*brSave=0;
392  TString saveName,saveDir,regPath;
393  char *savePath;
394  fTree->Clear();
395  while ((br = (StBranch*)nextBr())) {
396  if (strncmp("hist",br->GetName(),4)) continue;
397  brSave=br;
398  FillHistBranch(br);
399  }
400  if (!brSave) return 0;
401  regPath = brSave->GetFile();
402  if (!regPath.Contains(".root")) return 0;
403  saveDir = gSystem->DirName (regPath);
404  saveName = gSystem->BaseName(regPath);
405  saveName.Replace(0,0,"save.");
406  savePath = gSystem->ConcatFileName(saveDir,saveName);
407  brSave->Close();
408  brSave->SetFile((const char*)savePath);
409  brSave->WriteEvent((ULong_t)(-2));
410  fTree->Close("keep");
411  brSave->Close();
412  brSave->Clear();
413  brSave->SetFile((const char*)regPath);
414  delete [] savePath;
415  brSave->Open();
416 
417 
418  return 0;
419 }
420 //_____________________________________________________________________________
421 void StTreeMaker::Close(Option_t *)
422 {
423  if (fTree) {
424  m_DataSet->Remove(fTree); fTree->Close();
425  delete fTree; fTree=0;}
426  SetFile("");
427 }
428 //_____________________________________________________________________________
429 void StTreeMaker::Clear(Option_t *opt)
430 {
431  if (opt){/*touch*/}
432  if (fTree) {m_DataSet->Remove(fTree);fTree->Clear();}
433  m_DataSet->Delete();
434  if (fTree) m_DataSet->Add(fTree);
435 }
436 
437 
438 //_____________________________________________________________________________
439 //_____________________________________________________________________________
440 void StTreeMaker::FillHistBranch(StBranch *histBr)
441 {
442  int nAkt = 0;
443  StMaker *top,*upp;
444  St_DataSet *ds,*par,*dothist,*dotrcp;
445  const char *bname = histBr->GetName();
446 
447  top = this;
448  while((upp=GetMaker(top))) top = upp;
449 
450  St_DataSetIter nextDs(top,999);
451  while ((ds= nextDs())) { //loop over all stru
452  par = ds->GetParent();
453  if (!par) continue;
454  if (strcmp(".make",par->GetName())) continue;
455 
456  TString ts(ds->GetName());
457  if (strncmp(bname,"hist" ,4)==0) ts +="Hist";
458  if (strncmp(bname,"runco", 5)==0) ts +="Runco";
459 
460 
461  St_ObjectSet *os = new St_ObjectSet(ts);
462  ts = ((StMaker*)ds)->GetCVS();
463  if (ts.Contains("StMaker.h")
464  && ds->IsA() != StMaker::Class()) {// GetCVS not overloaded
465  ds->Warning("StMaker::Init","GetCVS is not overloaded");
466  printf(" Please add into file %s the following line: \n",ds->IsA()->GetDeclFileName());
467  printf(" virtual const char *GetCVS() const\n");
468  printf(" {static const char cvs[]=\"Tag %sName:$ %sId:$ built \"__DATE__\" \" __TIME__ ; return cvs;}\n\n","$","$");
469  }
470 
471  os->SetTitle(ts);
472  histBr->Add(os);
473 
474  if (strncmp(bname,"hist" ,4)==0) {//Hist Branch
475  dothist = ds->Find(".hist");
476  if (!dothist) {delete os;continue;}
477  TList *tl = (TList*)((St_ObjectSet*)dothist)->GetObject();
478  if (!tl || !tl->First()) {delete os;continue;}
479  nAkt++;
480  os->SetObject(tl,0);}
481 
482  if (strncmp(bname,"runco",5)==0) {//Run Control Branch
483  dotrcp = ds->Find(".runco");
484  if (!dotrcp) continue;
485  nAkt++;
486  os->Update(dotrcp); dotrcp->Delete();}
487 
488 
489  }
490  histBr->SetIOMode("0");
491  if (nAkt) histBr->SetIOMode("w");
492 
493 
494  //UpdateTree(2);
495 }
496 
497 static void RuncoHist(StTree *tree)
498 {
499 // special function to preset options. Keep backward compat
500  if(!tree) return;
501  St_DataSetIter nextBr(tree);
502  StBranch *br=0;
503  while ((br=(StBranch*)nextBr())) {//loop over branches
504  if (strcmp(br->GetName(),"histBranch" )==0) br->SetOption("const");
505  if (strcmp(br->GetName(),"runcoBranch")==0) br->SetOption("const");
506  }
507 }
508 
virtual TDataSet * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TDataSet.cxx:403
Definition: FJcore.h:367
virtual Int_t Finish()
virtual void AddData(TDataSet *data, const char *dir=".data")
User methods.
Definition: StMaker.cxx:332
Int_t fNIO
Main file name name.
Definition: StIOInterFace.h:33
TString fTreeName
r=read,w=write,u=update
Definition: StIOInterFace.h:31
virtual Int_t GetNumber() const
STAR methods.
Definition: StMaker.cxx:256
virtual void Delete(Option_t *opt="")
Definition: TDataSet.cxx:320
virtual void Remove(TDataSet *set)
Remiove the &quot;set&quot; from this TDataSet.
Definition: TDataSet.cxx:641
virtual Int_t Make()
virtual TDataSet * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TDataSet.cxx:437
virtual TObject * Clone(const char *newname="") const
the custom implementation fo the TObject::Clone
Definition: TDataSet.cxx:308
virtual void SetObject(TObject *obj)
The depricated method (left here for the sake of the backward compatibility)
Definition: TObjectSet.h:59
virtual Long_t GetNRows() const
Returns the number of the used rows for the wrapped table.
Definition: TTable.cxx:1388
virtual void Clear(Option_t *opt)
User defined functions.
virtual TObject * GetObject() const
The depricated method (left here for the sake of the backward compatibility)
Definition: TDataSet.cxx:428
virtual const char * GetName() const
special overload
Definition: StMaker.cxx:237
virtual Int_t Finish()
virtual void AddFirst(TDataSet *dataset)
Add TDataSet object at the beginning of the dataset list of this dataset.
Definition: TDataSet.cxx:283
virtual Int_t GetRunNumber() const
Returns the current RunNumber.
Definition: StMaker.cxx:1054
virtual void Shunt(TDataSet *newParent=0)
Definition: TDataSet.cxx:810
TString fFile
Tree name.
Definition: StIOInterFace.h:32
virtual TDataSet * FindByName(const char *name, const char *path="", Option_t *opt="") const
Definition: TDataSet.cxx:378
Definition: StFileI.h:13
virtual void Update()
Definition: TDataSet.cxx:864
Definition: StTree.h:84
Definition: Stypes.h:44
virtual TDataSet * Find(const char *path) const
Definition: TDataSet.cxx:362