00001
00002
00003
00004
00006 #include <Stiostream.h>
00007 #include "TError.h"
00008 #include "St_DataSetIter.h"
00009 #include "StTreeMaker.h"
00010 #include "StObject.h"
00011 TableImpl(dst_bfc_status);
00012
00013 ClassImp(StTreeMaker)
00014 static void RuncoHist(StTree *tree);
00015
00016
00017
00018 StTreeMaker::StTreeMaker(const char *name, const char *ioFile,const char *treeName )
00019 :StIOInterFace(name,"0")
00020 {
00021 fFile = ioFile; fIOMode="0";fTree=0;fFinished=0;
00022 fBfcStatus = new St_dst_bfc_status("BfcStatus",100);
00023 AddConst(fBfcStatus);
00024 fTreeName = treeName;
00025 if (! fTreeName ) {
00026 TDataSet *parent = GetParent();
00027 if (parent) {
00028 StIOInterFace *grandparent = (StIOInterFace *) parent->GetParent();
00029 if (grandparent) fTreeName = grandparent->GetTreeName();
00030 }
00031 }
00032 if ( !fTreeName ) {
00033 Warning("StTreeMaker", "%s default treeName == bfcTree is used",name);
00034 fTreeName = "bfcTree";
00035 }
00036 }
00037
00038 StTreeMaker::~StTreeMaker(){
00039 }
00040
00041 Int_t StTreeMaker::Open(const char*)
00042 {
00043 int i;
00044
00045 assert(strchr("rwu",fIOMode[0]));
00046 if(fTree) return 0;
00047
00048 if (fTreeName.IsNull()) SetTreeName();
00049
00050 if (GetDebug())
00051 printf("<%s(%s)::Init> TreeName = %s\n",ClassName(),GetName(),GetTreeName());
00052
00053
00054 if (fIOMode[0]=='r') {
00055
00056
00057
00058
00059 if (!fTree) {
00060 class TFilePtr {
00061 private:
00062 TFile *fFile;
00063 public:
00064 TFilePtr(TFile *f): fFile(f){;}
00065 ~TFilePtr(){ delete fFile;};
00066 operator TFile *(){ return fFile; }
00067 Bool_t IsZombie() const { return fFile?fFile->IsZombie():kTRUE;}
00068 };
00069 TFilePtr tf = TFile::Open(fFile,"read","BFC StTree file");
00070 if (tf.IsZombie()) {
00071 Error("Init","Wrong input file %s\n",(const char*)fFile);
00072 return kStErr;
00073 }
00074
00075
00076 fTree = StTree::GetTree(tf,GetTreeName()); assert(fTree);
00077 fTree->SetIOMode("0");
00078 if (GetDebug())
00079 printf("<%s(%s)::Init> FOUND Tree %s in file %s\n",
00080 ClassName(),GetName(),
00081 fTree->GetName(),fFile.Data());
00082
00083
00084 TString firstBr(fFile);
00085 i = firstBr.Last('.'); assert(i>0);
00086 firstBr.Replace(i,999,"");
00087 i = firstBr.Last('.'); assert(i>0);
00088 firstBr.Replace(0,i+1,"");
00089
00090 St_DataSet *fst = fTree->Find(firstBr);
00091 if (!fst) {
00092 firstBr+="Branch";
00093 fst = fTree->Find(firstBr);}
00094 if (fst) {
00095 ((StBranch*)fst)->SetIOMode("r");
00096 fst->Shunt(0); fTree->AddFirst(fst);
00097 printf("<%s(%s)::Init> Branch %s is MAIN in tree\n",ClassName(),GetName(),fst->GetName());
00098 }
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108 UpdateTree(0);
00109 fTree->SetFile(fFile,"r");
00110 fTree->SetUKey(0);
00111 AddData(fTree);
00112
00113 SetOutput(fTree);
00114
00115
00116 } else {
00117
00118
00119
00120 TString BaseName,FileName;
00121
00122
00123 fTree = 0;
00124 if (fIOMode[0]=='u') fTree = (StTree*)GetDataSet(GetTreeName());
00125 if (fTree) {
00126
00127 StMaker *mk = GetMaker(fTree); assert(mk);
00128 if (GetDebug())
00129 printf("<%s(%s)::Init> FOUND Tree %s.%s\n",
00130 ClassName(),GetName(),
00131 mk->GetName(),fTree->GetName());
00132
00133 } else {
00134
00135 fTree = new StTree(GetTreeName());
00136
00137 }
00138
00139
00140 UpdateTree(0);
00141 fTree->SetFile(fFile,"w");
00142 fTree->SetUKey(0);
00143 fTree->Close("keep");
00144 }
00145
00146 RuncoHist(fTree);
00147
00148 return 0;
00149 }
00150
00151 Int_t StTreeMaker::Init()
00152 {
00153 return Open();
00154 }
00155
00156 Int_t StTreeMaker::Skip(int nskip)
00157 {
00158 assert(fTree);
00159 return fTree->Skip(nskip);
00160 }
00161
00162
00163 Int_t StTreeMaker::Make(){
00164
00165 fNIO++;
00166 if (fIOMode[0]=='r') {
00167 int iret=0,ntry=13;
00168 while(1999) {
00169 iret = MakeRead();
00170 if (iret!=kStErr && ntry--) break;
00171 Warning("Make","%d *** ReadError ***\n",ntry);
00172 }
00173 return iret;
00174
00175 } else {
00176
00177 return MakeWrite();
00178
00179 }
00180 }
00181
00182 Int_t StTreeMaker::MakeRead(const StUKey &RunEvent){
00183
00184 TDataSet *xrefMain[2];
00185 int iret;
00186 xrefMain[0] = StXRefManager::GetMain();
00187
00188
00189 if (!RunEvent.IsNull()) iret = fTree->ReadEvent(RunEvent);
00190 else iret = fTree->NextEvent( );
00191
00192 StEvtHddr *hddr = GetEvtHddr();
00193 if (Debug()) hddr->Print("");
00194 if (iret) return iret;
00195 St_DataSetIter nextBr(fTree);
00196 StBranch *br ;
00197 while ((br = (StBranch*)nextBr())){
00198 SetOutput(br);
00199 TString tsBr(br->GetName());
00200 if (tsBr.Contains("Branch")) {
00201 TString tsName = tsBr;
00202 tsName.ReplaceAll("Branch","");
00203 if (!br->Find(tsName)) SetOutput(tsName,br);
00204 }
00205 int lv=1; if (strncmp("runco",br->GetName(),5)==0) lv = 2;
00206 SetOutputAll(br,lv);
00207
00208 if (!hddr) continue;
00209 StEvtHddr *runevt = (StEvtHddr*)br->FindByName("RunEvent");
00210 if (!runevt) continue;
00211 *hddr = *runevt;
00212
00213 }
00214 xrefMain[1] = StXRefManager::GetMain();
00215
00216 if (xrefMain[1] && xrefMain[1]!=xrefMain[0] && xrefMain[1]->GetParent()==0 )
00217 AddData(xrefMain[1]);
00218 return iret;
00219 }
00220
00221 Int_t StTreeMaker::MakeWrite()
00222 {
00223
00224
00225 MakeBfcStatus();
00226 if (!GetFailedMaker()) UpdateTree(1);
00227 UpdateHddr();
00228
00229
00230 Int_t k1 = GetRunNumber();
00231 Int_t k2 = GetEventNumber();
00232 if (k1 <= 0 || k2 <= 0) { k1 = GetNumber(); k2=0; }
00233 StUKey ukey(k1,k2);
00234 fTree->WriteEvent(ukey);
00235 fTree->Clear();
00236 return 0;
00237 }
00238
00239 Int_t StTreeMaker::MakeBfcStatus()
00240 {
00241 fBfcStatus->SetNRows(0);
00242 int nrows = 0;
00243 TDataSetIter nextMk(GetParentChain(),999);
00244 TDataSet *ds = 0;
00245 EDataSetPass kont=kContinue;
00246 const char *name=0;
00247 while ((ds = nextMk(kont)))
00248 {
00249 name = ds->GetName();
00250 kont = kContinue;
00251 if (strcmp(".make",name)==0) continue;
00252 kont = kPrune;
00253 if (name[0]=='.') continue;
00254 kont = kContinue;
00255 if (!ds->InheritsFrom(StMaker::Class())) continue;
00256 int ret = ((StMaker*)ds)->GetMakeReturn();
00257
00258 fBfcStatus->SetNRows(++nrows);
00259 char * mkName = (*fBfcStatus)[nrows-1].maker_name;
00260 mkName[0]=0; strncat(mkName,name,11);
00261 (*fBfcStatus)[nrows-1].status = ret;
00262 }
00263
00264 return 0;
00265 }
00266
00267 void StTreeMaker::UpdateHddr()
00268 {
00269
00270
00271 StBranch *br;
00272 Option_t *opt=0;
00273 St_DataSet *hd = GetEvtHddr();
00274 StMaker *failmk = GetFailedMaker();
00275 TString ts;
00276 if (failmk ) {
00277 ts = "discarded by ";
00278 ts += failmk->ClassName();
00279 ts += "::";
00280 ts += failmk->GetName();
00281 hd->SetTitle(ts);
00282 }
00283
00284 St_DataSetIter nextBr(fTree);
00285
00286 while ((br = (StBranch *)nextBr())) {
00287 if ((opt = br->GetOption()) && strstr(opt,"CONST")) continue;
00288 if (!failmk && !br->First()) continue;
00289 St_DataSet *ds = br;
00290 if (ds->First() && ds->First() == ds->Last()) ds = ds->First();
00291 if (ds->Find("RunEvent")) continue;
00292 St_DataSet *hdd = (St_DataSet*)hd->Clone();
00293 hdd->SetName ("RunEvent");
00294 hdd->SetTitle(ts);
00295 ds->AddFirst(hdd);
00296 if (fBfcStatus->GetNRows()) br->Add(fBfcStatus);
00297 }
00298 }
00299
00300
00301 void StTreeMaker::UpdateTree(Int_t flag)
00302 {
00303
00304
00305 StBranch *br;
00306 const char* logs;int nlog,isSetBr;
00307 St_DataSet *upd,*updList,*dat,*ds;
00308 const char *cc;
00309
00310 TString updName,updTitl,updFile,updMode,updOpt,tlog;
00311
00312 updList= Find(".branches");
00313 if (!updList) return;
00314 St_DataSetIter updNext(updList);
00315 while ((upd=updNext())) {
00316 updTitl = upd->GetTitle();
00317 updName = upd->GetName();
00318 updFile = ""; updMode = ""; updOpt = "";
00319 isSetBr = (updTitl.Index("SetBranch:")==0);
00320 if (isSetBr && flag!=0) continue;
00321
00322 if (isSetBr) {
00323 cc = strstr(updTitl,"file=");
00324 if (cc) updFile.Replace(0,0,cc+5,strcspn(cc+5," "));
00325 cc = strstr(updTitl,"mode=");
00326 if (cc) updMode.Replace(0,0,cc+5,strcspn(cc+5," "));
00327 cc = strstr(updTitl,"opt=");
00328 if (cc) updOpt.Replace (0,0,cc+4,strcspn(cc+4," "));
00329
00330 if (!updFile.IsNull()) delete upd;
00331 }
00332
00333 if (updName[0]=='*') {
00334 if (!updMode.IsNull() || !updFile.IsNull()) fTree->SetFile(updFile,updMode,1);
00335 continue;}
00336
00337 br = (StBranch*)fTree->Find(updName);
00338 if (!br) {br = new StBranch(updName,fTree);br->SetIOMode(fIOMode);}
00339 if (!updMode.IsNull() || !updFile.IsNull()) br->SetFile(updFile,updMode);
00340 if (!updOpt.IsNull()) br->SetOption((const char*)updOpt);
00341
00342 if (flag==0) continue;
00343
00344 logs = (const char*)updTitl;nlog=0;
00345 while(1999)
00346 {
00347 logs += nlog + strspn(logs+nlog," "); nlog = strcspn(logs," ");if(!nlog) break;
00348 tlog.Replace(0,999,logs,nlog);
00349 dat = GetDataSet(tlog); if (!dat) continue;
00350 if (dat->InheritsFrom(StMaker::Class())) dat = dat->Find(".data");
00351 if (!dat) continue;
00352 if (*dat->GetName()!='.' && !dat->InheritsFrom(StBranch::Class()))
00353 {
00354 br->Add(dat);
00355 } else {
00356 St_DataSetIter nextDs(dat);
00357 while((ds = nextDs())) br->Add(ds);
00358 }
00359 }
00360
00361 }
00362
00363 }
00364
00365 Int_t StTreeMaker::Finish()
00366 {
00367 if (fFinished) return 0;
00368 fFinished = 1999;
00369 if (!fTree) return 0;
00370 if (fIOMode[0]!='r') {
00371 St_DataSetIter nextBr(fTree);
00372 StBranch *br;
00373 fTree->Clear();
00374 while ((br = (StBranch*)nextBr())) {
00375 if (strncmp("hist" ,br->GetName(),4)
00376 && strncmp("runco",br->GetName(),5)) continue;
00377 FillHistBranch(br);
00378 }
00379 fTree->WriteEvent((ULong_t)(-2));
00380 fTree->Clear();
00381 }
00382 Close(); return 0;
00383 StIOInterFace::Finish();
00384 }
00385
00386 Int_t StTreeMaker::Save()
00387 {
00388 St_DataSetIter nextBr(fTree);
00389 StBranch *br,*brSave=0;
00390 TString saveName,saveDir,regPath;
00391 char *savePath;
00392 fTree->Clear();
00393 while ((br = (StBranch*)nextBr())) {
00394 if (strncmp("hist",br->GetName(),4)) continue;
00395 brSave=br;
00396 FillHistBranch(br);
00397 }
00398 if (!brSave) return 0;
00399 regPath = brSave->GetFile();
00400 if (!regPath.Contains(".root")) return 0;
00401 saveDir = gSystem->DirName (regPath);
00402 saveName = gSystem->BaseName(regPath);
00403 saveName.Replace(0,0,"save.");
00404 savePath = gSystem->ConcatFileName(saveDir,saveName);
00405 brSave->Close();
00406 brSave->SetFile((const char*)savePath);
00407 brSave->WriteEvent((ULong_t)(-2));
00408 fTree->Close("keep");
00409 brSave->Close();
00410 brSave->Clear();
00411 brSave->SetFile((const char*)regPath);
00412 delete [] savePath;
00413 brSave->Open();
00414
00415
00416 return 0;
00417 }
00418
00419 void StTreeMaker::Close(Option_t *)
00420 {
00421 if (fTree) {
00422 m_DataSet->Remove(fTree); fTree->Close();
00423 delete fTree; fTree=0;}
00424 SetFile("");
00425 }
00426
00427 void StTreeMaker::Clear(Option_t *opt)
00428 {
00429 if (opt){}
00430 if (fTree) {m_DataSet->Remove(fTree);fTree->Clear();}
00431 m_DataSet->Delete();
00432 if (fTree) m_DataSet->Add(fTree);
00433 }
00434
00435
00436
00437
00438 void StTreeMaker::FillHistBranch(StBranch *histBr)
00439 {
00440 int nAkt = 0;
00441 StMaker *top,*upp;
00442 St_DataSet *ds,*par,*dothist,*dotrcp;
00443 const char *bname = histBr->GetName();
00444
00445 top = this;
00446 while((upp=GetMaker(top))) top = upp;
00447
00448 St_DataSetIter nextDs(top,999);
00449 while ((ds= nextDs())) {
00450 par = ds->GetParent();
00451 if (!par) continue;
00452 if (strcmp(".make",par->GetName())) continue;
00453
00454 TString ts(ds->GetName());
00455 if (strncmp(bname,"hist" ,4)==0) ts +="Hist";
00456 if (strncmp(bname,"runco", 5)==0) ts +="Runco";
00457
00458
00459 St_ObjectSet *os = new St_ObjectSet(ts);
00460 ts = ((StMaker*)ds)->GetCVS();
00461 if (ts.Contains("StMaker.h")
00462 && ds->IsA() != StMaker::Class()) {
00463 ds->Warning("StMaker::Init","GetCVS is not overloaded");
00464 printf(" Please add into file %s the following line: \n",ds->IsA()->GetDeclFileName());
00465 printf(" virtual const char *GetCVS() const\n");
00466 printf(" {static const char cvs[]=\"Tag %sName:$ %sId:$ built \"__DATE__\" \"__TIME__ ; return cvs;}\n\n","$","$");
00467 }
00468
00469 os->SetTitle(ts);
00470 histBr->Add(os);
00471
00472 if (strncmp(bname,"hist" ,4)==0) {
00473 dothist = ds->Find(".hist");
00474 if (!dothist) {delete os;continue;}
00475 TList *tl = (TList*)((St_ObjectSet*)dothist)->GetObject();
00476 if (!tl || !tl->First()) {delete os;continue;}
00477 nAkt++;
00478 os->SetObject(tl,0);}
00479
00480 if (strncmp(bname,"runco",5)==0) {
00481 dotrcp = ds->Find(".runco");
00482 if (!dotrcp) continue;
00483 nAkt++;
00484 os->Update(dotrcp); dotrcp->Delete();}
00485
00486
00487 }
00488 histBr->SetIOMode("0");
00489 if (nAkt) histBr->SetIOMode("w");
00490
00491
00492
00493 }
00494
00495 static void RuncoHist(StTree *tree)
00496 {
00497
00498 if(!tree) return;
00499 St_DataSetIter nextBr(tree);
00500 StBranch *br=0;
00501 while ((br=(StBranch*)nextBr())) {
00502 if (strcmp(br->GetName(),"histBranch" )==0) br->SetOption("const");
00503 if (strcmp(br->GetName(),"runcoBranch")==0) br->SetOption("const");
00504 }
00505 }
00506