| 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; | 
| 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 | // | // | 
| 174 | if ( li->CheckLevel2File(thisrun) ){ | if ( li->CheckLevel2File(thisrun) ){ | 
| 175 | lList->Add(su); | lList->Add(su); | 
| 176 | } else { | } else { | 
| 177 | if ( DebugMode() ) printf(" RUN %s DISCARDED \n",Row->GetField(0)); | if ( DebugMode() ) printf(" RUN %s DISCARDED \n",Row->GetField(0)); | 
| 178 | }; | }; | 
| 179 | // | // | 
| 180 | }; | }; | 
| 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; | 
| 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 | // | // | 
| 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 = 99900000000LL; | Long64_t maxsize = 99900000000LL; | 
| 430 | // | // | 
| 431 | Target = TFile::Open((this->GetFilename()).Data(), "RECREATE" ); | 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 |  | // | 
| 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); | //    Target->SetCompressionLevel(2); | 
| 445 |  | Target->SetCompressionLevel(3); | 
| 446 |  | //Target->SetCompressionLevel(5); | 
| 447 | // | // | 
| 448 | fOpen = true; | fOpen = true; | 
| 449 | return(true); | return(true); | 
| 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 = 0; |  | 
|  | TKey *oldkey = 0; |  | 
|  | TH1::AddDirectory(kFALSE); // gain time, do not add the objects in the list in memory |  | 
|  | // |  | 
|  | while ( (key = (TKey*)nextkey()) ) { |  | 
|  | // |  | 
|  | //      printf(" target ls \n"); |  | 
|  | //      Target->ls(); |  | 
|  | // |  | 
|  | 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->IsTRK2() && !li->IsTRK1() && !li->IsTRKh() ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"Calorimeter") && !li->IsCAL2() && !li->IsCAL1() ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"ToF") && !li->IsTOF() ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"Trigger") && !li->IsTRG() ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"Anticounter") && !li->IsAC() ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"S4") && !li->IsS4() ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"NeutronD") && !li->IsND() ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"OrbitalInfo") && !li->IsORB() ) continue; |  | 
|  | // |  | 
|  | if ( !strcmp(key->GetName(),"Run") && !li->IsRUN() ) 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->SetCacheSize(0); |  | 
|  | // |  | 
|  | 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); |  | 
|  | }; |  | 
|  | // |  | 
|  | delete 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") ) { |  | 
|  | // |  | 
|  | Long64_t nfiles = 0; |  | 
|  | if ( fastMethod ){ |  | 
|  | //      globChain->Merge(target->GetFile(),0,"C keep fast"); |  | 
|  | nfiles=this->Mergy((TChain*)globChain,target->GetFile(),0,"C keep fast"); |  | 
|  | } else { |  | 
|  | //globChain->Merge(target->GetFile(),0,"C keep"); |  | 
|  | nfiles=this->Mergy((TChain*)globChain,target->GetFile(),0,"C keep"); |  | 
|  | }; |  | 
|  | // |  | 
|  | merged = true; |  | 
|  | // |  | 
|  | if ( DebugMode() ){ |  | 
|  | printf(" Merged %i files\n",(int)nfiles); |  | 
|  | globChain->ls(); |  | 
|  | }; |  | 
|  | // |  | 
|  | delete globChain; |  | 
|  | //      return; |  | 
|  | // |  | 
|  | } else { |  | 
|  | // |  | 
|  | //      obj->Write( key->GetName() ); // <================================================================================== |  | 
|  | // |  | 
|  | }; |  | 
|  | }; |  | 
|  | delete obj; |  | 
|  | 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){ | // 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 | //    // We must have been passed a file, we will use it | 
| 805 | // later to reset the compression level of the branches. | //    // later to reset the compression level of the branches. | 
| 806 | if (!file) { | //    if (!file) { | 
| 807 | // FIXME: We need an error message here. | //       // FIXME: We need an error message here. | 
| 808 | return 0; | //      printf(" 19 \n"); | 
| 809 | } | //      return 0; | 
| 810 |  | //    } | 
| 811 | // Options | //    printf(" 20 \n"); | 
| 812 | Bool_t fastClone = kFALSE; |  | 
| 813 | TString opt = option; | //    // Options | 
| 814 | opt.ToLower(); | //    Bool_t fastClone = kFALSE; | 
| 815 | if (opt.Contains("fast")) { | //    TString opt = option; | 
| 816 | fastClone = kTRUE; | //    opt.ToLower(); | 
| 817 | } | //    if (opt.Contains("fast")) { | 
| 818 |  | //       fastClone = kTRUE; | 
| 819 | // The chain tree must have a list of branches | //       printf(" 21 \n"); | 
| 820 | // because we may try to change their basket | //    } | 
| 821 | // size later. | //    // The chain tree must have a list of branches | 
| 822 | TObjArray* lbranches = mychain->GetListOfBranches(); | //    // because we may try to change their basket | 
| 823 | if (!lbranches) { | //    // size later. | 
| 824 | // FIXME: We need an error message here. | //    TObjArray* lbranches = mychain->GetListOfBranches(); | 
| 825 | return 0; | //    if (!lbranches) { | 
| 826 | } | //       // FIXME: We need an error message here. | 
| 827 |  | //      printf(" 22 \n"); | 
| 828 | // The chain must have a current tree because | //       return 0; | 
| 829 | // that is the one we will clone. | //    } | 
| 830 | //   if (!fTree) { |  | 
| 831 | // -- LoadTree() has not yet been called, no current tree. | //    //   file->cd(); | 
| 832 | // FIXME: We need an error message here. | //    // The chain must have a current tree because | 
| 833 | //      return 0; | //    // that is the one we will clone. | 
| 834 | //   } | //    //   if (!fTree) { | 
| 835 |  | //       // -- LoadTree() has not yet been called, no current tree. | 
| 836 | // Copy the chain's current tree without | //       // FIXME: We need an error message here. | 
| 837 | // copying any entries, we will do that later. | //    //      return 0; | 
| 838 | TTree* newTree = mychain->CloneTree(0); | //    //   } | 
| 839 | if (!newTree) { |  | 
| 840 | // FIXME: We need an error message here. | //    // Copy the chain's current tree without | 
| 841 | return 0; | //    // copying any entries, we will do that later. | 
| 842 | } | //    printf(" 23 \n"); | 
| 843 |  | //    TTree* newTree = mychain->CloneTree(0); | 
| 844 | // Strip out the (potential) directory name. | //    if (!newTree) { | 
| 845 | // FIXME: The merged chain may or may not have the | //       // FIXME: We need an error message here. | 
| 846 | //        same name as the original chain.  This is | //      printf(" 24 \n"); | 
| 847 | //        bad because the chain name determines the | //       return 0; | 
| 848 | //        names of the trees in the chain by default. | //    } | 
| 849 | newTree->SetName(gSystem->BaseName(mychain->GetName())); | //    printf(" 25 \n"); | 
| 850 |  |  | 
| 851 | // FIXME: Why do we do this? |  | 
| 852 | //   newTree->SetAutoSave(-1); | //    // Strip out the (potential) directory name. | 
| 853 | newTree->SetAutoSave(900000000000000LL); | //    // FIXME: The merged chain may or may not have the | 
| 854 |  | //    //        same name as the original chain.  This is | 
| 855 | // Circularity is incompatible with merging, it may | //    //        bad because the chain name determines the | 
| 856 | // force us to throw away entries, which is not what | //    //        names of the trees in the chain by default. | 
| 857 | // we are supposed to do. | //    printf(" 26 \n"); | 
| 858 | newTree->SetCircular(0); | //    newTree->SetName(gSystem->BaseName(mychain->GetName())); | 
| 859 |  | //    printf(" 27 \n"); | 
| 860 | // Reset the compression level of the branches. |  | 
| 861 | if (opt.Contains("c")) { | //    // FIXME: Why do we do this? | 
| 862 | TBranch* branch = 0; | //    //   newTree->SetAutoSave(-1); | 
| 863 | TIter nextb(newTree->GetListOfBranches()); | //    newTree->SetAutoSave(900000000000000LL); | 
| 864 | while ((branch = (TBranch*) nextb())) { |  | 
| 865 | branch->SetCompressionLevel(file->GetCompressionLevel()); | //    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 | // Reset the basket size of the branches. | //    newTree->SetCircular(0); | 
| 870 | if (basketsize > 1000) { |  | 
| 871 | TBranch* branch = 0; | //    // Reset the compression level of the branches. | 
| 872 | TIter nextb(newTree->GetListOfBranches()); | //    if (opt.Contains("c")) { | 
| 873 | while ((branch = (TBranch*) nextb())) { | //       TBranch* branch = 0; | 
| 874 | branch->SetBasketSize(basketsize); | //       TIter nextb(newTree->GetListOfBranches()); | 
| 875 | } | //       while ((branch = (TBranch*) nextb())) { | 
| 876 | } | //      printf(" 29 \n"); | 
| 877 |  | //          branch->SetCompressionLevel(file->GetCompressionLevel()); | 
| 878 | Long64_t nentries = mychain->GetEntriesFast(); | //       } | 
| 879 |  | //    } | 
| 880 | // Copy the entries. |  | 
| 881 | if (fastClone) { | //    printf(" 30 \n"); | 
| 882 | // For each tree in the chain. | //    // Reset the basket size of the branches. | 
| 883 | for (Long64_t i = 0; i < nentries; i += mychain->GetTree()->GetEntries()) { | //    if (basketsize > 1000) { | 
| 884 | if (mychain->LoadTree(i) < 0) { | //       TBranch* branch = 0; | 
| 885 | break; | //       TIter nextb(newTree->GetListOfBranches()); | 
| 886 | } | //       while ((branch = (TBranch*) nextb())) { | 
| 887 | TTreeCloner cloner(mychain->GetTree(), newTree, option); | //      printf(" 31 \n"); | 
| 888 | if (cloner.IsValid()) { | //          branch->SetBasketSize(basketsize); | 
| 889 | newTree->SetEntries(newTree->GetEntries() + mychain->GetTree()->GetEntries()); | //       } | 
| 890 | cloner.Exec(); | //    } | 
| 891 | } else { |  | 
| 892 | if (mychain->GetFile()) { | //    printf(" 32 \n"); | 
| 893 | printf("Merge Skipped file %s\n", mychain->GetFile()->GetName()); | //    Long64_t nentries = mychain->GetEntriesFast(); | 
| 894 | //            } else { | //    //Long64_t nentries = mychain->GetEntries(); | 
| 895 | //               Warning("Merge", "Skipped file number %d\n", fTreeNumber); |  | 
| 896 | } | //    // Copy the entries. | 
| 897 | } | //    if (fastClone) { | 
| 898 | } | //       // For each tree in the chain. | 
| 899 | } else { | //       for (Long64_t i = 0; i < nentries; i += mychain->GetTree()->GetEntries()) { | 
| 900 | for (Long64_t i = 0; i < nentries; i++) { | //          if (mychain->LoadTree(i) < 0) { | 
| 901 | if (mychain->GetEntry(i) <= 0) { | //             break; | 
| 902 | break; | //          } | 
| 903 | } | //          TTreeCloner cloner(mychain->GetTree(), newTree, option); | 
| 904 | newTree->Fill(); | //          if (cloner.IsValid()) { | 
| 905 | } | //             newTree->SetEntries(newTree->GetEntries() + mychain->GetTree()->GetEntries()); | 
| 906 | } | //             cloner.Exec(); | 
| 907 |  | //          } else { | 
| 908 | // Write the new tree header. | //             if (mychain->GetFile()) { | 
| 909 | newTree->Write(); | //            printf("Merge Skipped file %s\n", mychain->GetFile()->GetName()); | 
| 910 |  | //             //            } else { | 
| 911 | // Get our return value. | //             //               Warning("Merge", "Skipped file number %d\n", fTreeNumber); | 
| 912 | Int_t nfiles = newTree->GetFileNumber() + 1; | //             } | 
| 913 |  | //          } | 
| 914 | // Close and delete the current file of the new tree. | //       } | 
| 915 | if (!opt.Contains("keep")) { | //    } else { | 
| 916 | // FIXME: What happens to fDirectory in newTree here? | //      printf(" 33 %llu \n",nentries); | 
| 917 | delete newTree->GetCurrentFile(); | //      mychain->Print(); | 
| 918 | } | //      for (Long64_t i = 0; i < nentries; i++) { | 
| 919 | return nfiles; | //        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 |  | // } |