| 11 | #include <TFile.h> | #include <TFile.h> | 
| 12 | #include <TTree.h> | #include <TTree.h> | 
| 13 | #include <TTimeStamp.h> | #include <TTimeStamp.h> | 
| 14 |  | #include <TTreeCloner.h> | 
| 15 | #include <RunGlue.h> | #include <RunGlue.h> | 
| 16 | // | // | 
| 17 | ClassImp(RunGlue); | ClassImp(RunGlue); | 
| 25 | RunGlue::RunGlue(TSQLServer *da, UInt_t ru, TString di, TString wrkdi) { | RunGlue::RunGlue(TSQLServer *da, UInt_t ru, TString di, TString wrkdi) { | 
| 26 | fDBG = false; | fDBG = false; | 
| 27 | li = new PamLevel2(); | li = new PamLevel2(); | 
| 28 |  | //  li = 0; | 
| 29 | this->Clear(); | this->Clear(); | 
| 30 | dbc = da; | dbc = da; | 
| 31 | run = ru; | run = ru; | 
| 32 | dir = di; | dir = di; | 
| 33 | // | // | 
| 34 | TString wd = gSystem->WorkingDirectory(); | wd = gSystem->WorkingDirectory(); | 
| 35 | // | // | 
| 36 | outdir = wrkdi; | outdir = wrkdi; | 
| 37 | if ( !strcmp(outdir.Data(),"") ) outdir = wd; | if ( !strcmp(outdir.Data(),"") ) outdir = wd; | 
| 42 | runmode = false; | runmode = false; | 
| 43 | createlist = true; | createlist = true; | 
| 44 | }; | }; | 
| 45 |  | fUpgrade = true; | 
| 46 | // | // | 
| 47 | //  lList = new TList(); | //  lList = new TList(); | 
| 48 | // | // | 
| 49 | }; | }; | 
| 50 |  |  | 
|  |  |  | 
| 51 | void RunGlue::Clear() { | void RunGlue::Clear() { | 
| 52 | fEnd = false; | fEnd = false; | 
| 53 | run = 0; | run = 0; | 
| 76 | if (list.Contains("+ALL", TString::kIgnoreCase)) RUN = true; | if (list.Contains("+ALL", TString::kIgnoreCase)) RUN = true; | 
| 77 | // | // | 
| 78 | fDList = list; | fDList = list; | 
| 79 | li->SetWhichTrees(fDList); | //  li->SetWhichTrees(fDList); | 
| 80 | // | // | 
| 81 | if ( DebugMode() ) printf(" Detector list is %s \n",fDList.Data()); | if ( DebugMode() ) printf(" Detector list is %s \n",fDList.Data()); | 
| 82 | // | // | 
| 83 | }; | }; | 
| 84 |  |  | 
| 85 | TList *RunGlue::GetRunList(){ | TList *RunGlue::GetRunList(){ | 
| 86 | // | // | 
| 87 | lList = new TList(); | lList = new TList(); | 
| 88 | lList->Clear(); | lList->Clear(); | 
| 89 | TString thisrun; | TString thisrun; | 
| 115 | TTimeStamp *llim = new TTimeStamp(YY,MM,DD,0,0,0,0,true,0); | TTimeStamp *llim = new TTimeStamp(YY,MM,DD,0,0,0,0,true,0); | 
| 116 | // | // | 
| 117 | UInt_t lowerlimit = llim->GetSec(); | UInt_t lowerlimit = llim->GetSec(); | 
| 118 | UInt_t upperlimit = lowerlimit + 86401; | UInt_t upperlimit = lowerlimit + 86400; | 
|  | // |  | 
|  | stringstream myquery; |  | 
|  | myquery.str(""); |  | 
|  | myquery << "SELECT ID FROM GL_RUN WHERE RUNHEADER_TIME>=" << (UInt_t)lowerlimit |  | 
|  | << " AND RUNHEADER_TIME<" << (UInt_t)upperlimit << " ORDER BY RUNHEADER_TIME ASC;"; |  | 
|  | // |  | 
|  | pResult = dbc->Query(myquery.str().c_str()); |  | 
|  | for( UInt_t r=0; r < 1000; r++){ |  | 
|  | Row = pResult->Next(); |  | 
|  | if( Row == NULL ) break; |  | 
|  | if ( DebugMode() ) printf(" %u RUN %s \n",r,Row->GetField(0)); |  | 
|  | // |  | 
|  | thisrun=dir+(TString)Row->GetField(0)+".Level2.root"; |  | 
|  | // |  | 
|  | if ( DebugMode() ) printf(" Filename is %s \n",thisrun.Data()); |  | 
|  | // |  | 
|  | su = TFile::Open(thisrun); |  | 
|  | if ( li->CheckLevel2File(thisrun) ){ |  | 
|  | lList->Add(su); |  | 
|  | } else { |  | 
|  | if ( DebugMode() ) printf(" RUN %s DISCARDED \n",Row->GetField(0)); |  | 
|  | }; |  | 
|  | // |  | 
|  | }; |  | 
| 119 | // | // | 
| 120 | if ( DebugMode() ) printf(" YY %u MM %u DD %u ll %u ul %u \n",YY,MM,DD,lowerlimit,upperlimit); | if ( DebugMode() ) printf(" YY %u MM %u DD %u ll %u ul %u \n",YY,MM,DD,lowerlimit,upperlimit); | 
| 121 | // | // | 
| 150 | // | // | 
| 151 | printf(" Output filename is %s \n",fFilename.Data()); | printf(" Output filename is %s \n",fFilename.Data()); | 
| 152 | // | // | 
| 153 |  | if ( !this->OpenFile() ){ | 
| 154 |  | fEnd = true; | 
| 155 |  | return(0); | 
| 156 |  | }; | 
| 157 |  | // | 
| 158 |  | stringstream myquery; | 
| 159 |  | myquery.str(""); | 
| 160 |  | myquery << "SELECT ID FROM GL_RUN WHERE RUNHEADER_TIME>=" << (UInt_t)lowerlimit | 
| 161 |  | << " AND RUNHEADER_TIME<" << (UInt_t)upperlimit << " ORDER BY RUNHEADER_TIME ASC;"; | 
| 162 |  | // | 
| 163 |  | pResult = dbc->Query(myquery.str().c_str()); | 
| 164 |  | for( UInt_t r=0; r < 1000; r++){ | 
| 165 |  | Row = pResult->Next(); | 
| 166 |  | if( Row == NULL ) break; | 
| 167 |  | if ( DebugMode() ) printf(" %u RUN %s \n",r,Row->GetField(0)); | 
| 168 |  | // | 
| 169 |  | thisrun=dir+(TString)Row->GetField(0)+".Level2.root"; | 
| 170 |  | // | 
| 171 |  | if ( DebugMode() ) printf(" Filename is %s \n",thisrun.Data()); | 
| 172 |  | // | 
| 173 |  | su = TFile::Open(thisrun); | 
| 174 |  | if ( li->CheckLevel2File(thisrun) ){ | 
| 175 |  | lList->Add(su); | 
| 176 |  | } else { | 
| 177 |  | if ( DebugMode() ) printf(" RUN %s DISCARDED \n",Row->GetField(0)); | 
| 178 |  | }; | 
| 179 |  | // | 
| 180 |  | }; | 
| 181 |  | // | 
| 182 |  | // | 
| 183 | delete glrun; | delete glrun; | 
| 184 | delete dbtime; | delete dbtime; | 
| 185 | // | // | 
| 282 | TTimeStamp *llim = new TTimeStamp(YY,MM,DD,0,0,0,0,true,0); | TTimeStamp *llim = new TTimeStamp(YY,MM,DD,0,0,0,0,true,0); | 
| 283 | // | // | 
| 284 | UInt_t lowerlimit = llim->GetSec(); | UInt_t lowerlimit = llim->GetSec(); | 
| 285 | UInt_t upperlimit = lowerlimit + 86401; | UInt_t upperlimit = lowerlimit + 86400; | 
|  | // |  | 
|  | stringstream myquery; |  | 
|  | myquery.str(""); |  | 
|  | myquery << "SELECT ID FROM GL_RUN WHERE RUNHEADER_TIME>=" << (UInt_t)lowerlimit |  | 
|  | << " AND RUNHEADER_TIME<" << (UInt_t)upperlimit << " ORDER BY RUNHEADER_TIME ASC;"; |  | 
|  | // |  | 
|  | pResult = dbc->Query(myquery.str().c_str()); |  | 
|  | for( UInt_t r=0; r < 1000; r++){ |  | 
|  | Row = pResult->Next(); |  | 
|  | if( Row == NULL ) break; |  | 
|  | if ( DebugMode() ) printf(" %u RUN %s \n",r,Row->GetField(0)); |  | 
|  | // |  | 
|  | thisrun=dir+(TString)Row->GetField(0)+".Level2.root"; |  | 
|  | // |  | 
|  | if ( DebugMode() ) printf(" Filename is %s \n",thisrun.Data()); |  | 
|  | // |  | 
|  | su = TFile::Open(thisrun); |  | 
|  | if ( su ){ |  | 
|  | TFile *su0 = TFile::Open(thisrun); |  | 
|  | fDoneList->Add(su0); |  | 
|  | fNlistdone++; |  | 
|  | }; |  | 
|  | if ( li->CheckLevel2File(thisrun) ){ |  | 
|  | lList->Add(su); |  | 
|  | if ( DebugMode() ) printf(" RUN %s ADDED \n",Row->GetField(0)); |  | 
|  | } else { |  | 
|  | if ( DebugMode() ) printf(" RUN %s DISCARDED \n",Row->GetField(0)); |  | 
|  | }; |  | 
|  | // |  | 
|  | }; |  | 
| 286 | // | // | 
| 287 | if ( DebugMode() ) printf(" YY %u MM %u DD %u ll %u ul %u \n",YY,MM,DD,lowerlimit,upperlimit); | if ( DebugMode() ) printf(" YY %u MM %u DD %u ll %u ul %u \n",YY,MM,DD,lowerlimit,upperlimit); | 
| 288 | // | // | 
| 317 | // | // | 
| 318 | printf(" Output filename is %s \n",fFilename.Data()); | printf(" Output filename is %s \n",fFilename.Data()); | 
| 319 | // | // | 
| 320 |  | if ( !this->OpenFile() ) return(0); | 
| 321 |  | // | 
| 322 |  | stringstream myquery; | 
| 323 |  | myquery.str(""); | 
| 324 |  | myquery << "SELECT ID FROM GL_RUN WHERE RUNHEADER_TIME>=" << (UInt_t)lowerlimit | 
| 325 |  | << " AND RUNHEADER_TIME<" << (UInt_t)upperlimit << " ORDER BY RUNHEADER_TIME ASC;"; | 
| 326 |  | // | 
| 327 |  | pResult = dbc->Query(myquery.str().c_str()); | 
| 328 |  | for( UInt_t r=0; r < 1000; r++){ | 
| 329 |  | Row = pResult->Next(); | 
| 330 |  | if( Row == NULL ) break; | 
| 331 |  | if ( DebugMode() ) printf(" %u RUN %s \n",r,Row->GetField(0)); | 
| 332 |  | // | 
| 333 |  | thisrun=dir+(TString)Row->GetField(0)+".Level2.root"; | 
| 334 |  | // | 
| 335 |  | if ( DebugMode() ) printf(" Filename is %s \n",thisrun.Data()); | 
| 336 |  | // | 
| 337 |  | su = TFile::Open(thisrun); | 
| 338 |  | if ( su ){ | 
| 339 |  | TFile *su0 = TFile::Open(thisrun); | 
| 340 |  | fDoneList->Add(su0); | 
| 341 |  | fNlistdone++; | 
| 342 |  | }; | 
| 343 |  | if ( li->CheckLevel2File(thisrun) ){ | 
| 344 |  | lList->Add(su); | 
| 345 |  | if ( DebugMode() ) printf(" RUN %s ADDED \n",Row->GetField(0)); | 
| 346 |  | } else { | 
| 347 |  | if ( DebugMode() ) printf(" RUN %s DISCARDED \n",Row->GetField(0)); | 
| 348 |  | }; | 
| 349 |  | // | 
| 350 |  | }; | 
| 351 |  | // | 
| 352 | if ( DebugMode() ){ | if ( DebugMode() ){ | 
| 353 | UInt_t ll = 0; | UInt_t ll = 0; | 
| 354 | while ( (TFile*)lList->At(ll) ){ | while ( (TFile*)lList->At(ll) ){ | 
| 381 |  |  | 
| 382 | Bool_t RunGlue::OpenFile(){ | Bool_t RunGlue::OpenFile(){ | 
| 383 | // | // | 
| 384 |  | fOpen = false; | 
| 385 | printf(" Check if output file already exists \n"); | printf(" Check if output file already exists \n"); | 
| 386 | Target = TFile::Open((this->GetFilename()).Data(), "READ" ); | ifstream myfile; | 
| 387 | // | myfile.open((this->GetFilename()).Data()); | 
| 388 | if ( Target ){ | if ( myfile ){ | 
| 389 | Target->Close(); | //  Target = TFile::Open((this->GetFilename()).Data(), "READ" ); | 
| 390 |  | // | 
| 391 |  | //  if ( Target ){ | 
| 392 |  | //    Target->Close(); | 
| 393 |  | myfile.close(); | 
| 394 | printf("Error opening target file, %s  already exist!\n",(this->GetFilename()).Data()); | printf("Error opening target file, %s  already exist!\n",(this->GetFilename()).Data()); | 
| 395 | return(false); | return(false); | 
| 396 | } else { | } else { | 
| 397 | // | // | 
| 398 |  | // try to lock tables and work on a db level to avoid multiple file simultaneous access | 
| 399 |  | // | 
| 400 |  | stringstream oss; | 
| 401 |  | // | 
| 402 |  | if ( fUpgrade ){ | 
| 403 |  | oss.str(""); | 
| 404 |  | oss << "lock table GL_ROOT write;"; | 
| 405 |  | TSQLResult *result = 0; | 
| 406 |  | TSQLRow *row = 0; | 
| 407 |  | result = dbc->Query(oss.str().c_str()); | 
| 408 |  | oss.str(""); | 
| 409 |  | oss << "select ID from GL_ROOT where NAME='" << ((TString)gSystem->BaseName(this->GetFilename())).Data() << "';"; | 
| 410 |  | result = dbc->Query(oss.str().c_str()); | 
| 411 |  | row = result->Next(); | 
| 412 |  | if ( row ){ | 
| 413 |  | printf("Error opening target file (does %s exist? already in the DB? are the permissions ok?)\n",(this->GetFilename()).Data()); | 
| 414 |  | return(false); | 
| 415 |  | } else { | 
| 416 |  | oss.str(""); | 
| 417 |  | oss << "insert into GL_ROOT (PATH,NAME) values ('$PAM_L2','" << ((TString)gSystem->BaseName(this->GetFilename())).Data() << "');"; | 
| 418 |  | result = dbc->Query(oss.str().c_str()); | 
| 419 |  | }; | 
| 420 |  | oss.str(""); | 
| 421 |  | oss << "unlock tables;"; | 
| 422 |  | result = dbc->Query(oss.str().c_str()); | 
| 423 |  | }; | 
| 424 |  | //    Target = TFile::Open((this->GetFilename()).Data(), "RECREATE" ); | 
| 425 |  | Target = TFile::Open((this->GetFilename()).Data(), "NEW" ); | 
| 426 |  | // | 
| 427 | printf(" Output file does not exist, creating it\n"); | printf(" Output file does not exist, creating it\n"); | 
| 428 | // | // | 
| 429 | Long64_t maxsize = 10000000000LL; | Long64_t maxsize = 99900000000LL; | 
| 430 |  | // | 
| 431 |  | if ( !Target || Target->IsZombie()) { | 
| 432 |  | printf("Error opening target file (does %s exist? are the permissions ok?)\n",(this->GetFilename()).Data()); | 
| 433 |  | //      exit(1); | 
| 434 |  | return(false); | 
| 435 |  | } | 
| 436 |  | // | 
| 437 |  | Target->Write(); | 
| 438 | // | // | 
|  | Target = TFile::Open((this->GetFilename()).Data(), "RECREATE" ); |  | 
| 439 | //fastMethod = kTRUE; | //fastMethod = kTRUE; | 
| 440 | fastMethod = kFALSE; | fastMethod = kFALSE; | 
| 441 | // | // | 
|  | // |  | 
|  | if ( !Target || Target->IsZombie()) { |  | 
|  | printf("Error opening target file (does %s exist?)\n",(this->GetFilename()).Data()); |  | 
|  | exit(1); |  | 
|  | } |  | 
| 442 | // | // | 
| 443 | TTree::SetMaxTreeSize(maxsize); | TTree::SetMaxTreeSize(maxsize); | 
| 444 |  | //    Target->SetCompressionLevel(2); | 
| 445 |  | Target->SetCompressionLevel(3); | 
| 446 |  | //Target->SetCompressionLevel(5); | 
| 447 | // | // | 
| 448 |  | fOpen = true; | 
| 449 | return(true); | return(true); | 
| 450 | // | // | 
| 451 | }; | }; | 
| 505 | }; | }; | 
| 506 | // | // | 
| 507 | myquery.str(""); | myquery.str(""); | 
|  | myquery << "insert into GL_ROOT (ID_RAW,PATH,NAME) values (" << idr << ",'" << outdir.Data() << "','" << ((TString)gSystem->BaseName(this->GetFilename())).Data() << "');"; |  | 
|  | if ( DebugMode() ) printf(" query is %s \n",myquery.str().c_str()); |  | 
|  | // |  | 
|  | pResult = dbc->Query(myquery.str().c_str()); |  | 
|  | if ( !pResult ){ |  | 
|  | printf(" ERROR WRITING ON DB!\n"); |  | 
|  | return; |  | 
|  | }; |  | 
|  | myquery.str(""); |  | 
| 508 | myquery << "select ID from GL_ROOT where NAME='" << ((TString)gSystem->BaseName(this->GetFilename())).Data() << "';"; | myquery << "select ID from GL_ROOT where NAME='" << ((TString)gSystem->BaseName(this->GetFilename())).Data() << "';"; | 
| 509 | if ( DebugMode() ) printf(" query is %s \n",myquery.str().c_str()); | if ( DebugMode() ) printf(" query is %s \n",myquery.str().c_str()); | 
| 510 | // | // | 
| 520 | } else { | } else { | 
| 521 | idl2 = (UInt_t)atoll(Row->GetField(0)); | idl2 = (UInt_t)atoll(Row->GetField(0)); | 
| 522 | }; | }; | 
| 523 |  | myquery.str(""); | 
| 524 |  | //  myquery << "insert into GL_ROOT (ID_RAW,PATH,NAME) values (" << idr << ",'" << outdir.Data() << "','" << ((TString)gSystem->BaseName(this->GetFilename())).Data() << "');"; | 
| 525 |  | //  myquery << "insert into GL_ROOT (ID_RAW,PATH,NAME) values (" << idr << ",'$PAM_L2','" << ((TString)gSystem->BaseName(this->GetFilename())).Data() << "');"; | 
| 526 |  | myquery << "update GL_ROOT set ID_RAW=" << idr << " where ID=" << idl2 << ";"; | 
| 527 |  | if ( DebugMode() ) printf(" query is %s \n",myquery.str().c_str()); | 
| 528 |  | // | 
| 529 |  | pResult = dbc->Query(myquery.str().c_str()); | 
| 530 |  | if ( !pResult ){ | 
| 531 |  | printf(" ERROR WRITING ON DB!\n"); | 
| 532 |  | return; | 
| 533 |  | }; | 
| 534 | // | // | 
| 535 | // | // | 
| 536 | // | // | 
| 563 | // | // | 
| 564 | void RunGlue::MergeRootfile(TList *sourcelist) { | void RunGlue::MergeRootfile(TList *sourcelist) { | 
| 565 | // | // | 
| 566 | merged = false; | merged = true; | 
|  | // |  | 
|  | TDirectory *target = Target; |  | 
|  | // |  | 
|  | if ( DebugMode() ) printf("\nTarget path is: %s \n",target->GetPath()); |  | 
|  | // |  | 
|  | TString path( (char*)strstr( target->GetPath(), ":" ) ); |  | 
|  | path.Remove(0,2); |  | 
|  | // |  | 
|  | TDirectory *first_source = (TDirectory*)sourcelist->First(); |  | 
|  | THashList allNames; |  | 
|  | // |  | 
|  | while ( first_source ){ |  | 
|  | // |  | 
|  | TDirectory *current_sourcedir = first_source->GetDirectory(path); |  | 
|  | // |  | 
|  | if ( !current_sourcedir ){ |  | 
|  | first_source = (TDirectory*)sourcelist->After(first_source); |  | 
|  | continue; |  | 
|  | } |  | 
|  | // |  | 
|  | // loop over all keys in this directory |  | 
|  | // |  | 
|  | TChain *globChain = 0; |  | 
|  | TIter nextkey( current_sourcedir->GetListOfKeys() ); |  | 
|  | TKey *key, *oldkey=0; |  | 
|  | TH1::AddDirectory(kFALSE); // gain time, do not add the objects in the list in memory |  | 
|  | // |  | 
|  | while ( (key = (TKey*)nextkey()) ) { |  | 
|  | // |  | 
|  | if ( current_sourcedir == target ) break; |  | 
|  | // |  | 
|  | if (oldkey && !strcmp(oldkey->GetName(),key->GetName())) continue; //keep only the highest cycle number for each key |  | 
|  | // |  | 
|  | if (allNames.FindObject(key->GetName())) continue; |  | 
|  | // |  | 
|  | if ( DebugMode() ) printf(" Key name is -%s- \n",key->GetName()); |  | 
|  | // |  | 
|  | // |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"Tracker") && !li->TRK2 && !li->TRK1 && !li->TRKh ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"Calorimeter") && !li->CAL2 && !li->CAL1 ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"ToF") && !li->TOF ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"Trigger") && !li->TRG ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"Anticounter") && !li->AC ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"S4") && !li->S4 ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"NeutronD") && !li->ND ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"OrbitalInfo") && !li->ORB ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"Run") && !RUN ) continue; |  | 
|  | // |  | 
|  | if ( strcmp(key->GetName(),"Calorimeter") && strcmp(key->GetName(),"Tracker") && strcmp(key->GetName(),"ToF") && strcmp(key->GetName(),"Trigger") && strcmp(key->GetName(),"Anticounter") && strcmp(key->GetName(),"S4") && strcmp(key->GetName(),"NeutronD") && strcmp(key->GetName(),"OrbitalInfo") && strcmp(key->GetName(),"Run") && strcmp(key->GetName(),"ProcessID0") ){ |  | 
|  | if ( DebugMode() ) printf(" ERROR UNKNOWN KEY %s !\n",key->GetName()); |  | 
|  | continue; |  | 
|  | }; |  | 
|  | // |  | 
|  | allNames.Add(new TObjString(key->GetName())); |  | 
|  | // |  | 
|  | // read object from first source file |  | 
|  | // |  | 
|  | current_sourcedir->cd(); |  | 
|  | TObject *obj = key->ReadObj(); |  | 
|  | // |  | 
|  | if ( obj->IsA()->InheritsFrom("TTree") ){ |  | 
|  | // |  | 
|  | // loop over all source files create a chain of Trees "globChain" |  | 
|  | // |  | 
|  | TString obj_name; |  | 
|  | // |  | 
|  | if ( path.Length() ) { |  | 
|  | obj_name = path + "/" + obj->GetName(); |  | 
|  | } else { |  | 
|  | obj_name = obj->GetName(); |  | 
|  | }; |  | 
|  | // |  | 
|  | globChain = new TChain(obj_name); |  | 
|  | // |  | 
|  | globChain->Add(first_source->GetName()); |  | 
|  | // |  | 
|  | TFile *nextsource = (TFile*)sourcelist->After( first_source ); |  | 
|  | // |  | 
|  | while ( nextsource ) { |  | 
|  | // |  | 
|  | //do not add to the list a file that does not contain this Tree |  | 
|  | // |  | 
|  | TFile *curf = TFile::Open(nextsource->GetName()); |  | 
|  | // |  | 
|  | if ( curf ) { |  | 
|  | // |  | 
|  | Bool_t mustAdd = kFALSE; |  | 
|  | // |  | 
|  | if (curf->FindKey(obj_name)) { |  | 
|  | // |  | 
|  | mustAdd = kTRUE; |  | 
|  | // |  | 
|  | } else { |  | 
|  | // |  | 
|  | //we could be more clever here. No need to import the object |  | 
|  | //we are missing a function in TDirectory |  | 
|  | // |  | 
|  | TObject *aobj = curf->Get(obj_name); |  | 
|  | // |  | 
|  | if ( aobj ){ |  | 
|  | mustAdd = kTRUE; |  | 
|  | delete aobj; |  | 
|  | }; |  | 
|  | }; |  | 
|  | if (mustAdd) { |  | 
|  | globChain->Add(nextsource->GetName()); |  | 
|  | }; |  | 
|  | }; |  | 
|  | delete curf; |  | 
|  | nextsource = (TFile*)sourcelist->After(nextsource); |  | 
|  | }; |  | 
|  | // |  | 
|  | } else { |  | 
|  | // |  | 
|  | // object is of no type that we know or can handle |  | 
|  | // |  | 
|  | if ( DebugMode() ) cout << "Unknown object type, name: " |  | 
|  | << obj->GetName() << " title: " << obj->GetTitle() << endl; |  | 
|  | }; |  | 
|  | // |  | 
|  | // now write the merged histogram (which is "in" obj) to the target file |  | 
|  | // note that this will just store obj in the current directory level, |  | 
|  | // which is not persistent until the complete directory itself is stored |  | 
|  | // by "target->Write()" below |  | 
|  | // |  | 
|  | if ( obj ){ |  | 
|  | // |  | 
|  | target->cd(); |  | 
|  | // |  | 
|  | if( obj->IsA()->InheritsFrom("TTree") ) { |  | 
|  | // |  | 
|  | // |  | 
|  | if ( fastMethod ){ |  | 
|  | globChain->Merge(target->GetFile(),0,"keep fast"); |  | 
|  | } else { |  | 
|  | globChain->Merge(target->GetFile(),0,"keep"); |  | 
|  | }; |  | 
|  | // |  | 
|  | merged = true; |  | 
|  | // |  | 
|  | if ( DebugMode() ) globChain->ls(); |  | 
|  | // |  | 
|  | delete globChain; |  | 
|  | // |  | 
|  | } else { |  | 
|  | // |  | 
|  | //      obj->Write( key->GetName() ); // <================================================================================== |  | 
|  | // |  | 
|  | }; |  | 
|  | }; |  | 
|  | oldkey = key; |  | 
|  | }; |  | 
|  | // |  | 
|  | first_source = (TDirectory*)sourcelist->After(first_source); |  | 
|  | // |  | 
|  | }; |  | 
|  | // save modifications to target file |  | 
|  | target->SaveSelf(kTRUE); |  | 
| 567 | // | // | 
| 568 | } | //  if ( li ) li->Delete(); | 
| 569 |  | PamLevel2 *nli = new PamLevel2(wd,sourcelist,fDList); | 
| 570 |  | nli->SetSELLI(2); | 
| 571 |  | // | 
| 572 |  | Target->cd(); | 
| 573 |  | // | 
| 574 |  | nli->CreateCloneTrees(Target); | 
| 575 |  | // | 
| 576 |  | nli->GetCloneTree("Tracker")->SetAutoSave(900000000000000LL); | 
| 577 |  | nli->GetCloneTree("Trigger")->SetAutoSave(900000000000000LL); | 
| 578 |  | nli->GetCloneTree("Calorimeter")->SetAutoSave(900000000000000LL); | 
| 579 |  | nli->GetCloneTree("S4")->SetAutoSave(900000000000000LL); | 
| 580 |  | nli->GetCloneTree("Anticounter")->SetAutoSave(900000000000000LL); | 
| 581 |  | nli->GetCloneTree("NeutronD")->SetAutoSave(900000000000000LL); | 
| 582 |  | nli->GetCloneTree("OrbitalInfo")->SetAutoSave(900000000000000LL); | 
| 583 |  | nli->GetCloneTree("Run")->SetAutoSave(900000000000000LL); | 
| 584 |  | nli->GetCloneTree("ToF")->SetAutoSave(900000000000000LL); | 
| 585 |  | // | 
| 586 |  | ULong64_t nevents = nli->GetEntries(); | 
| 587 |  | printf(" NEVENTS %llu \n",nevents); | 
| 588 |  | for(ULong64_t iev=0; iev<nevents; iev++){ | 
| 589 |  | nli->Clear(); | 
| 590 |  | if( nli->GetEntry(iev) ){ | 
| 591 |  | nli->FillCloneTrees(); | 
| 592 |  | }; | 
| 593 |  | }; | 
| 594 |  | Target->cd(); | 
| 595 |  | nli->WriteCloneTrees(); | 
| 596 |  | printf("Written file %s \n",Target->GetName()); | 
| 597 |  | //  Target->Write(); | 
| 598 |  | //  TTree *slist = (TTree*)Target->Get("SelectionList"); | 
| 599 |  | //  slist->Delete("all"); | 
| 600 |  | Target->Close(); | 
| 601 |  |  | 
| 602 |  | //   // | 
| 603 |  | //   TDirectory *target = Target; | 
| 604 |  | //   // | 
| 605 |  | //   if ( DebugMode() ) printf("\nTarget path is: %s \n",target->GetPath()); | 
| 606 |  | //   // | 
| 607 |  | //   TString path( (char*)strstr( target->GetPath(), ":" ) ); | 
| 608 |  | //   path.Remove(0,2); | 
| 609 |  | //   // | 
| 610 |  | //   TDirectory *first_source = (TDirectory*)sourcelist->First(); | 
| 611 |  | //   THashList allNames; | 
| 612 |  | //   // | 
| 613 |  | //   while ( first_source ){ | 
| 614 |  | //     // | 
| 615 |  | //     TDirectory *current_sourcedir = first_source->GetDirectory(path); | 
| 616 |  | //     // | 
| 617 |  | //     if ( !current_sourcedir ){ | 
| 618 |  | //       first_source = (TDirectory*)sourcelist->After(first_source); | 
| 619 |  | //       continue; | 
| 620 |  | //     } | 
| 621 |  | //     // | 
| 622 |  | //     // loop over all keys in this directory | 
| 623 |  | //     // | 
| 624 |  | //     TChain *globChain = 0; | 
| 625 |  | //     TIter nextkey( current_sourcedir->GetListOfKeys() ); | 
| 626 |  | //     TKey *key = 0; | 
| 627 |  | //     TKey *oldkey = 0; | 
| 628 |  | //     TH1::AddDirectory(kFALSE); // gain time, do not add the objects in the list in memory | 
| 629 |  | //     // | 
| 630 |  | //     while ( (key = (TKey*)nextkey()) ) { | 
| 631 |  | //       // | 
| 632 |  | //       //      printf(" target ls \n"); | 
| 633 |  | //       //      Target->ls(); | 
| 634 |  | //       // | 
| 635 |  | //       if ( current_sourcedir == target ) break; | 
| 636 |  | //       // | 
| 637 |  | //       if ( oldkey && !strcmp(oldkey->GetName(),key->GetName()) ) continue; //keep only the highest cycle number for each key | 
| 638 |  | //       // | 
| 639 |  | //       if ( allNames.FindObject(key->GetName()) ) continue; | 
| 640 |  | //       // | 
| 641 |  | //       if ( DebugMode() ) printf(" Key name is -%s- \n",key->GetName()); | 
| 642 |  | //       // | 
| 643 |  | //       // | 
| 644 |  | //       // | 
| 645 |  | //       if ( !strcmp(key->GetName(),"Tracker") && !li->IsTRK2() && !li->IsTRK1() && !li->IsTRKh() ) continue; | 
| 646 |  | //       // | 
| 647 |  | //       if ( !strcmp(key->GetName(),"Calorimeter") && !li->IsCAL2() && !li->IsCAL1() ) continue; | 
| 648 |  | //       // | 
| 649 |  | //       if ( !strcmp(key->GetName(),"ToF") && !li->IsTOF() ) continue; | 
| 650 |  | //       // | 
| 651 |  | //       if ( !strcmp(key->GetName(),"Trigger") && !li->IsTRG() ) continue; | 
| 652 |  | //       // | 
| 653 |  | //       if ( !strcmp(key->GetName(),"Anticounter") && !li->IsAC() ) continue; | 
| 654 |  | //       // | 
| 655 |  | //       if ( !strcmp(key->GetName(),"S4") && !li->IsS4() ) continue; | 
| 656 |  | //       // | 
| 657 |  | //       if ( !strcmp(key->GetName(),"NeutronD") && !li->IsND() ) continue; | 
| 658 |  | //       // | 
| 659 |  | //       if ( !strcmp(key->GetName(),"OrbitalInfo") && !li->IsORB() ) continue; | 
| 660 |  | //       // | 
| 661 |  | //       if ( !strcmp(key->GetName(),"Run") && !li->IsRUN() ) continue; | 
| 662 |  | //       // | 
| 663 |  | //       if ( strcmp(key->GetName(),"Calorimeter") && strcmp(key->GetName(),"Tracker") && strcmp(key->GetName(),"ToF") && strcmp(key->GetName(),"Trigger") && strcmp(key->GetName(),"Anticounter") && strcmp(key->GetName(),"S4") && strcmp(key->GetName(),"NeutronD") && strcmp(key->GetName(),"OrbitalInfo") && strcmp(key->GetName(),"Run") && strcmp(key->GetName(),"ProcessID0") ){ | 
| 664 |  | //      if ( DebugMode() ) printf(" ERROR UNKNOWN KEY %s !\n",key->GetName()); | 
| 665 |  | //      continue; | 
| 666 |  | //       }; | 
| 667 |  | //       // | 
| 668 |  | //       printf(" 1 \n"); | 
| 669 |  | //       allNames.Add(new TObjString(key->GetName())); | 
| 670 |  | //       printf(" 2 \n"); | 
| 671 |  | //       // | 
| 672 |  | //       // read object from first source file | 
| 673 |  | //       // | 
| 674 |  | //       current_sourcedir->cd(); | 
| 675 |  | //       TObject *obj = key->ReadObj(); | 
| 676 |  | //       printf(" 3 \n"); | 
| 677 |  | //       // | 
| 678 |  | //       if ( obj->IsA()->InheritsFrom("TTree") ){ | 
| 679 |  | //      // | 
| 680 |  | //              // loop over all source files create a chain of Trees "globChain" | 
| 681 |  | //      // | 
| 682 |  | //      TString obj_name; | 
| 683 |  | //      printf(" 4 \n"); | 
| 684 |  | //      // | 
| 685 |  | //      if ( path.Length() ) { | 
| 686 |  | //        obj_name = path + "/" + obj->GetName(); | 
| 687 |  | //      } else { | 
| 688 |  | //        obj_name = obj->GetName(); | 
| 689 |  | //      }; | 
| 690 |  | //      // | 
| 691 |  | //      globChain = new TChain(obj_name); | 
| 692 |  | //      // | 
| 693 |  | //      globChain->SetCacheSize(0); | 
| 694 |  | //      // | 
| 695 |  | //      printf(" 5 \n"); | 
| 696 |  | //      globChain->Add(first_source->GetName()); | 
| 697 |  | //      printf(" 6 \n"); | 
| 698 |  | //      // | 
| 699 |  | //      TFile *nextsource = (TFile*)sourcelist->After( first_source ); | 
| 700 |  | //      // | 
| 701 |  | //      while ( nextsource ) { | 
| 702 |  | //        // | 
| 703 |  | //        //do not add to the list a file that does not contain this Tree | 
| 704 |  | //        // | 
| 705 |  | //        printf(" 7 \n"); | 
| 706 |  | //        TFile *curf = TFile::Open(nextsource->GetName()); | 
| 707 |  | //        // | 
| 708 |  | //        if ( curf ) { | 
| 709 |  | //          // | 
| 710 |  | //          Bool_t mustAdd = kFALSE; | 
| 711 |  | //          // | 
| 712 |  | //          if (curf->FindKey(obj_name)) { | 
| 713 |  | //            // | 
| 714 |  | //            mustAdd = kTRUE; | 
| 715 |  | //            // | 
| 716 |  | //          } else { | 
| 717 |  | //            // | 
| 718 |  | //            //we could be more clever here. No need to import the object | 
| 719 |  | //            //we are missing a function in TDirectory | 
| 720 |  | //            // | 
| 721 |  | //            TObject *aobj = curf->Get(obj_name); | 
| 722 |  | //            // | 
| 723 |  | //            if ( aobj ){ | 
| 724 |  | //              mustAdd = kTRUE; | 
| 725 |  | //              delete aobj; | 
| 726 |  | //            }; | 
| 727 |  | //          }; | 
| 728 |  | //          if (mustAdd) { | 
| 729 |  | //            printf(" 8 \n"); | 
| 730 |  | //            globChain->Add(nextsource->GetName()); | 
| 731 |  | //            printf(" 9 \n"); | 
| 732 |  | //          }; | 
| 733 |  | //        }; | 
| 734 |  | //        delete curf; | 
| 735 |  | //        nextsource = (TFile*)sourcelist->After(nextsource); | 
| 736 |  | //      }; | 
| 737 |  | //      // | 
| 738 |  | //      printf(" 10 \n"); | 
| 739 |  | //      delete nextsource; | 
| 740 |  | //      printf(" 11 \n"); | 
| 741 |  | //      // | 
| 742 |  | //       } else { | 
| 743 |  | //      // | 
| 744 |  | //      // object is of no type that we know or can handle | 
| 745 |  | //      // | 
| 746 |  | //      if ( DebugMode() ) cout << "Unknown object type, name: " | 
| 747 |  | //           << obj->GetName() << " title: " << obj->GetTitle() << endl; | 
| 748 |  | //       }; | 
| 749 |  | //       // | 
| 750 |  | //       // now write the merged histogram (which is "in" obj) to the target file | 
| 751 |  | //       // note that this will just store obj in the current directory level, | 
| 752 |  | //       // which is not persistent until the complete directory itself is stored | 
| 753 |  | //       // by "target->Write()" below | 
| 754 |  | //       // | 
| 755 |  | //       printf(" 12 \n"); | 
| 756 |  | //       if ( obj ){ | 
| 757 |  | //      // | 
| 758 |  | //      target->cd(); | 
| 759 |  | //      // | 
| 760 |  | //      if( obj->IsA()->InheritsFrom("TTree") ) { | 
| 761 |  | //        // | 
| 762 |  | //        Long64_t nfiles = 0; | 
| 763 |  | //        if ( fastMethod ){ | 
| 764 |  | //          //      globChain->Merge(target->GetFile(),0,"C keep fast"); | 
| 765 |  | //          nfiles=this->Mergy((TChain*)globChain,target->GetFile(),0,"C keep fast"); | 
| 766 |  | //        } else { | 
| 767 |  | //          //globChain->Merge(target->GetFile(),0,"C keep"); | 
| 768 |  | //          printf(" 13 %llu \n",globChain->GetEntries()); | 
| 769 |  | //          nfiles=this->Mergy((TChain*)globChain,target->GetFile(),0,"C keep"); | 
| 770 |  | //          printf(" 14 \n"); | 
| 771 |  | //        }; | 
| 772 |  | //        // | 
| 773 |  | //        merged = true; | 
| 774 |  | //        // | 
| 775 |  | //        if ( DebugMode() ){ | 
| 776 |  | //          printf(" Merged %i files\n",(int)nfiles); | 
| 777 |  | //          globChain->ls(); | 
| 778 |  | //        }; | 
| 779 |  | //        // | 
| 780 |  | //        delete globChain; | 
| 781 |  | //        //      return; | 
| 782 |  | //        // | 
| 783 |  | //      } else { | 
| 784 |  | //        // | 
| 785 |  | //        //      obj->Write( key->GetName() ); // <================================================================================== | 
| 786 |  | //        // | 
| 787 |  | //      }; | 
| 788 |  | //       }; | 
| 789 |  | //       delete obj; | 
| 790 |  | //       oldkey = key; | 
| 791 |  | //     }; | 
| 792 |  | //     // | 
| 793 |  | //     first_source = (TDirectory*)sourcelist->After(first_source); | 
| 794 |  | //     // | 
| 795 |  | //   }; | 
| 796 |  | //   // save modifications to target file | 
| 797 |  | //   // | 
| 798 |  | //   target->SaveSelf(kTRUE); | 
| 799 |  | //   // | 
| 800 |  | }; | 
| 801 |  |  | 
| 802 |  |  | 
| 803 |  | // Long64_t RunGlue::Mergy(TChain *mychain, TFile* file, Int_t basketsize, Option_t* option){ | 
| 804 |  | //    // We must have been passed a file, we will use it | 
| 805 |  | //    // later to reset the compression level of the branches. | 
| 806 |  | //    if (!file) { | 
| 807 |  | //       // FIXME: We need an error message here. | 
| 808 |  | //      printf(" 19 \n"); | 
| 809 |  | //      return 0; | 
| 810 |  | //    } | 
| 811 |  | //    printf(" 20 \n"); | 
| 812 |  |  | 
| 813 |  | //    // Options | 
| 814 |  | //    Bool_t fastClone = kFALSE; | 
| 815 |  | //    TString opt = option; | 
| 816 |  | //    opt.ToLower(); | 
| 817 |  | //    if (opt.Contains("fast")) { | 
| 818 |  | //       fastClone = kTRUE; | 
| 819 |  | //       printf(" 21 \n"); | 
| 820 |  | //    } | 
| 821 |  | //    // The chain tree must have a list of branches | 
| 822 |  | //    // because we may try to change their basket | 
| 823 |  | //    // size later. | 
| 824 |  | //    TObjArray* lbranches = mychain->GetListOfBranches(); | 
| 825 |  | //    if (!lbranches) { | 
| 826 |  | //       // FIXME: We need an error message here. | 
| 827 |  | //      printf(" 22 \n"); | 
| 828 |  | //       return 0; | 
| 829 |  | //    } | 
| 830 |  |  | 
| 831 |  | //    //   file->cd(); | 
| 832 |  | //    // The chain must have a current tree because | 
| 833 |  | //    // that is the one we will clone. | 
| 834 |  | //    //   if (!fTree) { | 
| 835 |  | //       // -- LoadTree() has not yet been called, no current tree. | 
| 836 |  | //       // FIXME: We need an error message here. | 
| 837 |  | //    //      return 0; | 
| 838 |  | //    //   } | 
| 839 |  |  | 
| 840 |  | //    // Copy the chain's current tree without | 
| 841 |  | //    // copying any entries, we will do that later. | 
| 842 |  | //    printf(" 23 \n"); | 
| 843 |  | //    TTree* newTree = mychain->CloneTree(0); | 
| 844 |  | //    if (!newTree) { | 
| 845 |  | //       // FIXME: We need an error message here. | 
| 846 |  | //      printf(" 24 \n"); | 
| 847 |  | //       return 0; | 
| 848 |  | //    } | 
| 849 |  | //    printf(" 25 \n"); | 
| 850 |  |  | 
| 851 |  |  | 
| 852 |  | //    // Strip out the (potential) directory name. | 
| 853 |  | //    // FIXME: The merged chain may or may not have the | 
| 854 |  | //    //        same name as the original chain.  This is | 
| 855 |  | //    //        bad because the chain name determines the | 
| 856 |  | //    //        names of the trees in the chain by default. | 
| 857 |  | //    printf(" 26 \n"); | 
| 858 |  | //    newTree->SetName(gSystem->BaseName(mychain->GetName())); | 
| 859 |  | //    printf(" 27 \n"); | 
| 860 |  |  | 
| 861 |  | //    // FIXME: Why do we do this? | 
| 862 |  | //    //   newTree->SetAutoSave(-1); | 
| 863 |  | //    newTree->SetAutoSave(900000000000000LL); | 
| 864 |  |  | 
| 865 |  | //    printf(" 28 \n"); | 
| 866 |  | //    // Circularity is incompatible with merging, it may | 
| 867 |  | //    // force us to throw away entries, which is not what | 
| 868 |  | //    // we are supposed to do. | 
| 869 |  | //    newTree->SetCircular(0); | 
| 870 |  |  | 
| 871 |  | //    // Reset the compression level of the branches. | 
| 872 |  | //    if (opt.Contains("c")) { | 
| 873 |  | //       TBranch* branch = 0; | 
| 874 |  | //       TIter nextb(newTree->GetListOfBranches()); | 
| 875 |  | //       while ((branch = (TBranch*) nextb())) { | 
| 876 |  | //      printf(" 29 \n"); | 
| 877 |  | //          branch->SetCompressionLevel(file->GetCompressionLevel()); | 
| 878 |  | //       } | 
| 879 |  | //    } | 
| 880 |  |  | 
| 881 |  | //    printf(" 30 \n"); | 
| 882 |  | //    // Reset the basket size of the branches. | 
| 883 |  | //    if (basketsize > 1000) { | 
| 884 |  | //       TBranch* branch = 0; | 
| 885 |  | //       TIter nextb(newTree->GetListOfBranches()); | 
| 886 |  | //       while ((branch = (TBranch*) nextb())) { | 
| 887 |  | //      printf(" 31 \n"); | 
| 888 |  | //          branch->SetBasketSize(basketsize); | 
| 889 |  | //       } | 
| 890 |  | //    } | 
| 891 |  |  | 
| 892 |  | //    printf(" 32 \n"); | 
| 893 |  | //    Long64_t nentries = mychain->GetEntriesFast(); | 
| 894 |  | //    //Long64_t nentries = mychain->GetEntries(); | 
| 895 |  |  | 
| 896 |  | //    // Copy the entries. | 
| 897 |  | //    if (fastClone) { | 
| 898 |  | //       // For each tree in the chain. | 
| 899 |  | //       for (Long64_t i = 0; i < nentries; i += mychain->GetTree()->GetEntries()) { | 
| 900 |  | //          if (mychain->LoadTree(i) < 0) { | 
| 901 |  | //             break; | 
| 902 |  | //          } | 
| 903 |  | //          TTreeCloner cloner(mychain->GetTree(), newTree, option); | 
| 904 |  | //          if (cloner.IsValid()) { | 
| 905 |  | //             newTree->SetEntries(newTree->GetEntries() + mychain->GetTree()->GetEntries()); | 
| 906 |  | //             cloner.Exec(); | 
| 907 |  | //          } else { | 
| 908 |  | //             if (mychain->GetFile()) { | 
| 909 |  | //            printf("Merge Skipped file %s\n", mychain->GetFile()->GetName()); | 
| 910 |  | //             //            } else { | 
| 911 |  | //             //               Warning("Merge", "Skipped file number %d\n", fTreeNumber); | 
| 912 |  | //             } | 
| 913 |  | //          } | 
| 914 |  | //       } | 
| 915 |  | //    } else { | 
| 916 |  | //      printf(" 33 %llu \n",nentries); | 
| 917 |  | //      mychain->Print(); | 
| 918 |  | //      for (Long64_t i = 0; i < nentries; i++) { | 
| 919 |  | //        printf(" i %llu \n",i); | 
| 920 |  | //        // for (Long64_t i = 0; i < 1; i++) { | 
| 921 |  | //          if (mychain->GetEntry(i) <= 0) { | 
| 922 |  | //             break; | 
| 923 |  | //          } | 
| 924 |  | //          newTree->Fill(); | 
| 925 |  | //       } | 
| 926 |  | //       printf(" 34 \n"); | 
| 927 |  | //    } | 
| 928 |  |  | 
| 929 |  | //    // Write the new tree header. | 
| 930 |  | //    printf(" 35 \n"); | 
| 931 |  | //    newTree->Write(); | 
| 932 |  |  | 
| 933 |  | //    printf(" 36 \n"); | 
| 934 |  | //    // Get our return value. | 
| 935 |  | //    Int_t nfiles = newTree->GetFileNumber() + 1; | 
| 936 |  |  | 
| 937 |  | //    // Close and delete the current file of the new tree. | 
| 938 |  | //    if (!opt.Contains("keep")) { | 
| 939 |  | //       // FIXME: What happens to fDirectory in newTree here? | 
| 940 |  | //       delete newTree->GetCurrentFile(); | 
| 941 |  | //    } | 
| 942 |  | //    return nfiles; | 
| 943 |  | // } |