| 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 | // | // | 
| 383 | // | // | 
| 384 | fOpen = false; | 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 = 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()); |  | 
| 567 | // | // | 
| 568 | TString path( (char*)strstr( target->GetPath(), ":" ) ); | //  if ( li ) li->Delete(); | 
| 569 | path.Remove(0,2); | PamLevel2 *nli = new PamLevel2(wd,sourcelist,fDList); | 
| 570 | // | nli->SetSELLI(2); | 
| 571 | TDirectory *first_source = (TDirectory*)sourcelist->First(); | // | 
| 572 | THashList allNames; | Target->cd(); | 
| 573 | // | // | 
| 574 | while ( first_source ){ | nli->CreateCloneTrees(Target); | 
| 575 | // | // | 
| 576 | TDirectory *current_sourcedir = first_source->GetDirectory(path); | /*  nli->GetCloneTree("Tracker")->SetAutoSave(900000000000000LL); | 
| 577 | // | nli->GetCloneTree("Trigger")->SetAutoSave(900000000000000LL); | 
| 578 | if ( !current_sourcedir ){ | nli->GetCloneTree("Calorimeter")->SetAutoSave(900000000000000LL); | 
| 579 | first_source = (TDirectory*)sourcelist->After(first_source); | nli->GetCloneTree("S4")->SetAutoSave(900000000000000LL); | 
| 580 | continue; | 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 |  | if ( !nli->GetCloneTree("ProcessingInfo") ){ | 
| 601 |  | TChain *P = new TChain("ProcessingInfo"); | 
| 602 |  | // loop over files and create chains | 
| 603 |  | TIter next(sourcelist); | 
| 604 |  | TSystemFile *questo = 0; | 
| 605 |  | while ((questo = (TSystemFile*) next())) { | 
| 606 |  | TString name = questo->GetName(); | 
| 607 |  | P->Add(name); | 
| 608 | } | } | 
| 609 | // | if ( P->GetEntries() ){ | 
| 610 | // loop over all keys in this directory | TTree *Pclone = P->CloneTree(); | 
| 611 | // | Target->cd(); | 
| 612 | TChain *globChain = 0; | Pclone->Write("ProcessingInfo",TObject::kOverwrite); | 
| 613 | TIter nextkey( current_sourcedir->GetListOfKeys() ); | P->Delete(); | 
| 614 | TKey *key = 0; | P=0; | 
| 615 | TKey *oldkey = 0; | } | 
| 616 | TH1::AddDirectory(kFALSE); // gain time, do not add the objects in the list in memory | } | 
| 617 | // | // | 
| 618 | while ( (key = (TKey*)nextkey()) ) { | Target->Close(); | 
| 619 | // |  | 
| 620 | //      printf(" target ls \n"); | //   // | 
| 621 | //      Target->ls(); | //   TDirectory *target = Target; | 
| 622 | // | //   // | 
| 623 | if ( current_sourcedir == target ) break; | //   if ( DebugMode() ) printf("\nTarget path is: %s \n",target->GetPath()); | 
| 624 | // | //   // | 
| 625 | if ( oldkey && !strcmp(oldkey->GetName(),key->GetName()) ) continue; //keep only the highest cycle number for each key | //   TString path( (char*)strstr( target->GetPath(), ":" ) ); | 
| 626 | // | //   path.Remove(0,2); | 
| 627 | if ( allNames.FindObject(key->GetName()) ) continue; | //   // | 
| 628 | // | //   TDirectory *first_source = (TDirectory*)sourcelist->First(); | 
| 629 | if ( DebugMode() ) printf(" Key name is -%s- \n",key->GetName()); | //   THashList allNames; | 
| 630 | // | //   // | 
| 631 | // | //   while ( first_source ){ | 
| 632 | // | //     // | 
| 633 | if ( !strcmp(key->GetName(),"Tracker") && !li->TRK2 && !li->TRK1 && !li->TRKh ) continue; | //     TDirectory *current_sourcedir = first_source->GetDirectory(path); | 
| 634 | // | //     // | 
| 635 | if ( !strcmp(key->GetName(),"Calorimeter") && !li->CAL2 && !li->CAL1 ) continue; | //     if ( !current_sourcedir ){ | 
| 636 | // | //       first_source = (TDirectory*)sourcelist->After(first_source); | 
| 637 | if ( !strcmp(key->GetName(),"ToF") && !li->TOF ) continue; | //       continue; | 
| 638 | // | //     } | 
| 639 | if ( !strcmp(key->GetName(),"Trigger") && !li->TRG ) continue; | //     // | 
| 640 | // | //     // loop over all keys in this directory | 
| 641 | if ( !strcmp(key->GetName(),"Anticounter") && !li->AC ) continue; | //     // | 
| 642 | // | //     TChain *globChain = 0; | 
| 643 | if ( !strcmp(key->GetName(),"S4") && !li->S4 ) continue; | //     TIter nextkey( current_sourcedir->GetListOfKeys() ); | 
| 644 | // | //     TKey *key = 0; | 
| 645 | if ( !strcmp(key->GetName(),"NeutronD") && !li->ND ) continue; | //     TKey *oldkey = 0; | 
| 646 | // | //     TH1::AddDirectory(kFALSE); // gain time, do not add the objects in the list in memory | 
| 647 | if ( !strcmp(key->GetName(),"OrbitalInfo") && !li->ORB ) continue; | //     // | 
| 648 | // | //     while ( (key = (TKey*)nextkey()) ) { | 
| 649 | if ( !strcmp(key->GetName(),"Run") && !RUN ) continue; | //       // | 
| 650 | // | //       //      printf(" target ls \n"); | 
| 651 | 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") ){ | //       //      Target->ls(); | 
| 652 | if ( DebugMode() ) printf(" ERROR UNKNOWN KEY %s !\n",key->GetName()); | //       // | 
| 653 | continue; | //       if ( current_sourcedir == target ) break; | 
| 654 | }; | //       // | 
| 655 | // | //       if ( oldkey && !strcmp(oldkey->GetName(),key->GetName()) ) continue; //keep only the highest cycle number for each key | 
| 656 | allNames.Add(new TObjString(key->GetName())); | //       // | 
| 657 | // | //       if ( allNames.FindObject(key->GetName()) ) continue; | 
| 658 | // read object from first source file | //       // | 
| 659 | // | //       if ( DebugMode() ) printf(" Key name is -%s- \n",key->GetName()); | 
| 660 | current_sourcedir->cd(); | //       // | 
| 661 | TObject *obj = key->ReadObj(); | //       // | 
| 662 | // | //       // | 
| 663 | if ( obj->IsA()->InheritsFrom("TTree") ){ | //       if ( !strcmp(key->GetName(),"Tracker") && !li->IsTRK2() && !li->IsTRK1() && !li->IsTRKh() ) continue; | 
| 664 | // | //       // | 
| 665 | // loop over all source files create a chain of Trees "globChain" | //       if ( !strcmp(key->GetName(),"Calorimeter") && !li->IsCAL2() && !li->IsCAL1() ) continue; | 
| 666 | // | //       // | 
| 667 | TString obj_name; | //       if ( !strcmp(key->GetName(),"ToF") && !li->IsTOF() ) continue; | 
| 668 | // | //       // | 
| 669 | if ( path.Length() ) { | //       if ( !strcmp(key->GetName(),"Trigger") && !li->IsTRG() ) continue; | 
| 670 | obj_name = path + "/" + obj->GetName(); | //       // | 
| 671 | } else { | //       if ( !strcmp(key->GetName(),"Anticounter") && !li->IsAC() ) continue; | 
| 672 | obj_name = obj->GetName(); | //       // | 
| 673 | }; | //       if ( !strcmp(key->GetName(),"S4") && !li->IsS4() ) continue; | 
| 674 | // | //       // | 
| 675 | globChain = new TChain(obj_name); | //       if ( !strcmp(key->GetName(),"NeutronD") && !li->IsND() ) continue; | 
| 676 | // | //       // | 
| 677 | globChain->Add(first_source->GetName()); | //       if ( !strcmp(key->GetName(),"OrbitalInfo") && !li->IsORB() ) continue; | 
| 678 | // | //       // | 
| 679 | TFile *nextsource = (TFile*)sourcelist->After( first_source ); | //       if ( !strcmp(key->GetName(),"Run") && !li->IsRUN() ) continue; | 
| 680 | // | //       // | 
| 681 | while ( nextsource ) { | //       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") ){ | 
| 682 | // | //      if ( DebugMode() ) printf(" ERROR UNKNOWN KEY %s !\n",key->GetName()); | 
| 683 | //do not add to the list a file that does not contain this Tree | //      continue; | 
| 684 | // | //       }; | 
| 685 | TFile *curf = TFile::Open(nextsource->GetName()); | //       // | 
| 686 | // | //       printf(" 1 \n"); | 
| 687 | if ( curf ) { | //       allNames.Add(new TObjString(key->GetName())); | 
| 688 | // | //       printf(" 2 \n"); | 
| 689 | Bool_t mustAdd = kFALSE; | //       // | 
| 690 | // | //       // read object from first source file | 
| 691 | if (curf->FindKey(obj_name)) { | //       // | 
| 692 | // | //       current_sourcedir->cd(); | 
| 693 | mustAdd = kTRUE; | //       TObject *obj = key->ReadObj(); | 
| 694 | // | //       printf(" 3 \n"); | 
| 695 | } else { | //       // | 
| 696 | // | //       if ( obj->IsA()->InheritsFrom("TTree") ){ | 
| 697 | //we could be more clever here. No need to import the object | //      // | 
| 698 | //we are missing a function in TDirectory | //              // loop over all source files create a chain of Trees "globChain" | 
| 699 | // | //      // | 
| 700 | TObject *aobj = curf->Get(obj_name); | //      TString obj_name; | 
| 701 | // | //      printf(" 4 \n"); | 
| 702 | if ( aobj ){ | //      // | 
| 703 | mustAdd = kTRUE; | //      if ( path.Length() ) { | 
| 704 | delete aobj; | //        obj_name = path + "/" + obj->GetName(); | 
| 705 | }; | //      } else { | 
| 706 | }; | //        obj_name = obj->GetName(); | 
| 707 | if (mustAdd) { | //      }; | 
| 708 | globChain->Add(nextsource->GetName()); | //      // | 
| 709 | }; | //      globChain = new TChain(obj_name); | 
| 710 | }; | //      // | 
| 711 | delete curf; | //      globChain->SetCacheSize(0); | 
| 712 | nextsource = (TFile*)sourcelist->After(nextsource); | //      // | 
| 713 | }; | //      printf(" 5 \n"); | 
| 714 | // | //      globChain->Add(first_source->GetName()); | 
| 715 | delete nextsource; | //      printf(" 6 \n"); | 
| 716 | // | //      // | 
| 717 | } else { | //      TFile *nextsource = (TFile*)sourcelist->After( first_source ); | 
| 718 | // | //      // | 
| 719 | // object is of no type that we know or can handle | //      while ( nextsource ) { | 
| 720 | // | //        // | 
| 721 | if ( DebugMode() ) cout << "Unknown object type, name: " | //        //do not add to the list a file that does not contain this Tree | 
| 722 | << obj->GetName() << " title: " << obj->GetTitle() << endl; | //        // | 
| 723 | }; | //        printf(" 7 \n"); | 
| 724 | // | //        TFile *curf = TFile::Open(nextsource->GetName()); | 
| 725 | // now write the merged histogram (which is "in" obj) to the target file | //        // | 
| 726 | // note that this will just store obj in the current directory level, | //        if ( curf ) { | 
| 727 | // which is not persistent until the complete directory itself is stored | //          // | 
| 728 | // by "target->Write()" below | //          Bool_t mustAdd = kFALSE; | 
| 729 | // | //          // | 
| 730 | if ( obj ){ | //          if (curf->FindKey(obj_name)) { | 
| 731 | // | //            // | 
| 732 | target->cd(); | //            mustAdd = kTRUE; | 
| 733 | // | //            // | 
| 734 | if( obj->IsA()->InheritsFrom("TTree") ) { | //          } else { | 
| 735 | // | //            // | 
| 736 | Long64_t nfiles = 0; | //            //we could be more clever here. No need to import the object | 
| 737 | if ( fastMethod ){ | //            //we are missing a function in TDirectory | 
| 738 | //      globChain->Merge(target->GetFile(),0,"C keep fast"); | //            // | 
| 739 | nfiles=this->Mergy((TChain*)globChain,target->GetFile(),0,"C keep fast"); | //            TObject *aobj = curf->Get(obj_name); | 
| 740 | } else { | //            // | 
| 741 | //globChain->Merge(target->GetFile(),0,"C keep"); | //            if ( aobj ){ | 
| 742 | nfiles=this->Mergy((TChain*)globChain,target->GetFile(),0,"C keep"); | //              mustAdd = kTRUE; | 
| 743 | }; | //              delete aobj; | 
| 744 | // | //            }; | 
| 745 | merged = true; | //          }; | 
| 746 | // | //          if (mustAdd) { | 
| 747 | if ( DebugMode() ){ | //            printf(" 8 \n"); | 
| 748 | printf(" Merged %i files\n",(int)nfiles); | //            globChain->Add(nextsource->GetName()); | 
| 749 | globChain->ls(); | //            printf(" 9 \n"); | 
| 750 | }; | //          }; | 
| 751 | // | //        }; | 
| 752 | delete globChain; | //        delete curf; | 
| 753 | //      return; | //        nextsource = (TFile*)sourcelist->After(nextsource); | 
| 754 | // | //      }; | 
| 755 | } else { | //      // | 
| 756 | // | //      printf(" 10 \n"); | 
| 757 | //      obj->Write( key->GetName() ); // <================================================================================== | //      delete nextsource; | 
| 758 | // | //      printf(" 11 \n"); | 
| 759 | }; | //      // | 
| 760 | }; | //       } else { | 
| 761 | delete obj; | //      // | 
| 762 | oldkey = key; | //      // object is of no type that we know or can handle | 
| 763 | }; | //      // | 
| 764 | // | //      if ( DebugMode() ) cout << "Unknown object type, name: " | 
| 765 | first_source = (TDirectory*)sourcelist->After(first_source); | //           << obj->GetName() << " title: " << obj->GetTitle() << endl; | 
| 766 | // | //       }; | 
| 767 | }; | //       // | 
| 768 | // save modifications to target file | //       // now write the merged histogram (which is "in" obj) to the target file | 
| 769 | // | //       // note that this will just store obj in the current directory level, | 
| 770 | target->SaveSelf(kTRUE); | //       // which is not persistent until the complete directory itself is stored | 
| 771 | // | //       // by "target->Write()" below | 
| 772 |  | //       // | 
| 773 |  | //       printf(" 12 \n"); | 
| 774 |  | //       if ( obj ){ | 
| 775 |  | //      // | 
| 776 |  | //      target->cd(); | 
| 777 |  | //      // | 
| 778 |  | //      if( obj->IsA()->InheritsFrom("TTree") ) { | 
| 779 |  | //        // | 
| 780 |  | //        Long64_t nfiles = 0; | 
| 781 |  | //        if ( fastMethod ){ | 
| 782 |  | //          //      globChain->Merge(target->GetFile(),0,"C keep fast"); | 
| 783 |  | //          nfiles=this->Mergy((TChain*)globChain,target->GetFile(),0,"C keep fast"); | 
| 784 |  | //        } else { | 
| 785 |  | //          //globChain->Merge(target->GetFile(),0,"C keep"); | 
| 786 |  | //          printf(" 13 %llu \n",globChain->GetEntries()); | 
| 787 |  | //          nfiles=this->Mergy((TChain*)globChain,target->GetFile(),0,"C keep"); | 
| 788 |  | //          printf(" 14 \n"); | 
| 789 |  | //        }; | 
| 790 |  | //        // | 
| 791 |  | //        merged = true; | 
| 792 |  | //        // | 
| 793 |  | //        if ( DebugMode() ){ | 
| 794 |  | //          printf(" Merged %i files\n",(int)nfiles); | 
| 795 |  | //          globChain->ls(); | 
| 796 |  | //        }; | 
| 797 |  | //        // | 
| 798 |  | //        delete globChain; | 
| 799 |  | //        //      return; | 
| 800 |  | //        // | 
| 801 |  | //      } else { | 
| 802 |  | //        // | 
| 803 |  | //        //      obj->Write( key->GetName() ); // <================================================================================== | 
| 804 |  | //        // | 
| 805 |  | //      }; | 
| 806 |  | //       }; | 
| 807 |  | //       delete obj; | 
| 808 |  | //       oldkey = key; | 
| 809 |  | //     }; | 
| 810 |  | //     // | 
| 811 |  | //     first_source = (TDirectory*)sourcelist->After(first_source); | 
| 812 |  | //     // | 
| 813 |  | //   }; | 
| 814 |  | //   // save modifications to target file | 
| 815 |  | //   // | 
| 816 |  | //   target->SaveSelf(kTRUE); | 
| 817 |  | //   // | 
| 818 | }; | }; | 
| 819 |  |  | 
| 820 |  |  | 
| 821 | 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){ | 
| 822 | // We must have been passed a file, we will use it | //    // We must have been passed a file, we will use it | 
| 823 | // later to reset the compression level of the branches. | //    // later to reset the compression level of the branches. | 
| 824 | if (!file) { | //    if (!file) { | 
| 825 | // FIXME: We need an error message here. | //       // FIXME: We need an error message here. | 
| 826 | return 0; | //      printf(" 19 \n"); | 
| 827 | } | //      return 0; | 
| 828 |  | //    } | 
| 829 | // Options | //    printf(" 20 \n"); | 
| 830 | Bool_t fastClone = kFALSE; |  | 
| 831 | TString opt = option; | //    // Options | 
| 832 | opt.ToLower(); | //    Bool_t fastClone = kFALSE; | 
| 833 | if (opt.Contains("fast")) { | //    TString opt = option; | 
| 834 | fastClone = kTRUE; | //    opt.ToLower(); | 
| 835 | } | //    if (opt.Contains("fast")) { | 
| 836 |  | //       fastClone = kTRUE; | 
| 837 | // The chain tree must have a list of branches | //       printf(" 21 \n"); | 
| 838 | // because we may try to change their basket | //    } | 
| 839 | // size later. | //    // The chain tree must have a list of branches | 
| 840 | TObjArray* lbranches = mychain->GetListOfBranches(); | //    // because we may try to change their basket | 
| 841 | if (!lbranches) { | //    // size later. | 
| 842 | // FIXME: We need an error message here. | //    TObjArray* lbranches = mychain->GetListOfBranches(); | 
| 843 | return 0; | //    if (!lbranches) { | 
| 844 | } | //       // FIXME: We need an error message here. | 
| 845 |  | //      printf(" 22 \n"); | 
| 846 | // The chain must have a current tree because | //       return 0; | 
| 847 | // that is the one we will clone. | //    } | 
| 848 | //   if (!fTree) { |  | 
| 849 | // -- LoadTree() has not yet been called, no current tree. | //    //   file->cd(); | 
| 850 | // FIXME: We need an error message here. | //    // The chain must have a current tree because | 
| 851 | //      return 0; | //    // that is the one we will clone. | 
| 852 | //   } | //    //   if (!fTree) { | 
| 853 |  | //       // -- LoadTree() has not yet been called, no current tree. | 
| 854 | // Copy the chain's current tree without | //       // FIXME: We need an error message here. | 
| 855 | // copying any entries, we will do that later. | //    //      return 0; | 
| 856 | TTree* newTree = mychain->CloneTree(0); | //    //   } | 
| 857 | if (!newTree) { |  | 
| 858 | // FIXME: We need an error message here. | //    // Copy the chain's current tree without | 
| 859 | return 0; | //    // copying any entries, we will do that later. | 
| 860 | } | //    printf(" 23 \n"); | 
| 861 |  | //    TTree* newTree = mychain->CloneTree(0); | 
| 862 | // Strip out the (potential) directory name. | //    if (!newTree) { | 
| 863 | // FIXME: The merged chain may or may not have the | //       // FIXME: We need an error message here. | 
| 864 | //        same name as the original chain.  This is | //      printf(" 24 \n"); | 
| 865 | //        bad because the chain name determines the | //       return 0; | 
| 866 | //        names of the trees in the chain by default. | //    } | 
| 867 | newTree->SetName(gSystem->BaseName(mychain->GetName())); | //    printf(" 25 \n"); | 
| 868 |  |  | 
| 869 | // FIXME: Why do we do this? |  | 
| 870 | //   newTree->SetAutoSave(-1); | //    // Strip out the (potential) directory name. | 
| 871 | newTree->SetAutoSave(900000000000000LL); | //    // FIXME: The merged chain may or may not have the | 
| 872 |  | //    //        same name as the original chain.  This is | 
| 873 | // Circularity is incompatible with merging, it may | //    //        bad because the chain name determines the | 
| 874 | // force us to throw away entries, which is not what | //    //        names of the trees in the chain by default. | 
| 875 | // we are supposed to do. | //    printf(" 26 \n"); | 
| 876 | newTree->SetCircular(0); | //    newTree->SetName(gSystem->BaseName(mychain->GetName())); | 
| 877 |  | //    printf(" 27 \n"); | 
| 878 | // Reset the compression level of the branches. |  | 
| 879 | if (opt.Contains("c")) { | //    // FIXME: Why do we do this? | 
| 880 | TBranch* branch = 0; | //    //   newTree->SetAutoSave(-1); | 
| 881 | TIter nextb(newTree->GetListOfBranches()); | //    newTree->SetAutoSave(900000000000000LL); | 
| 882 | while ((branch = (TBranch*) nextb())) { |  | 
| 883 | branch->SetCompressionLevel(file->GetCompressionLevel()); | //    printf(" 28 \n"); | 
| 884 | } | //    // Circularity is incompatible with merging, it may | 
| 885 | } | //    // force us to throw away entries, which is not what | 
| 886 |  | //    // we are supposed to do. | 
| 887 | // Reset the basket size of the branches. | //    newTree->SetCircular(0); | 
| 888 | if (basketsize > 1000) { |  | 
| 889 | TBranch* branch = 0; | //    // Reset the compression level of the branches. | 
| 890 | TIter nextb(newTree->GetListOfBranches()); | //    if (opt.Contains("c")) { | 
| 891 | while ((branch = (TBranch*) nextb())) { | //       TBranch* branch = 0; | 
| 892 | branch->SetBasketSize(basketsize); | //       TIter nextb(newTree->GetListOfBranches()); | 
| 893 | } | //       while ((branch = (TBranch*) nextb())) { | 
| 894 | } | //      printf(" 29 \n"); | 
| 895 |  | //          branch->SetCompressionLevel(file->GetCompressionLevel()); | 
| 896 | Long64_t nentries = mychain->GetEntriesFast(); | //       } | 
| 897 |  | //    } | 
| 898 | // Copy the entries. |  | 
| 899 | if (fastClone) { | //    printf(" 30 \n"); | 
| 900 | // For each tree in the chain. | //    // Reset the basket size of the branches. | 
| 901 | for (Long64_t i = 0; i < nentries; i += mychain->GetTree()->GetEntries()) { | //    if (basketsize > 1000) { | 
| 902 | if (mychain->LoadTree(i) < 0) { | //       TBranch* branch = 0; | 
| 903 | break; | //       TIter nextb(newTree->GetListOfBranches()); | 
| 904 | } | //       while ((branch = (TBranch*) nextb())) { | 
| 905 | TTreeCloner cloner(mychain->GetTree(), newTree, option); | //      printf(" 31 \n"); | 
| 906 | if (cloner.IsValid()) { | //          branch->SetBasketSize(basketsize); | 
| 907 | newTree->SetEntries(newTree->GetEntries() + mychain->GetTree()->GetEntries()); | //       } | 
| 908 | cloner.Exec(); | //    } | 
| 909 | } else { |  | 
| 910 | if (mychain->GetFile()) { | //    printf(" 32 \n"); | 
| 911 | printf("Merge Skipped file %s\n", mychain->GetFile()->GetName()); | //    Long64_t nentries = mychain->GetEntriesFast(); | 
| 912 | //            } else { | //    //Long64_t nentries = mychain->GetEntries(); | 
| 913 | //               Warning("Merge", "Skipped file number %d\n", fTreeNumber); |  | 
| 914 | } | //    // Copy the entries. | 
| 915 | } | //    if (fastClone) { | 
| 916 | } | //       // For each tree in the chain. | 
| 917 | } else { | //       for (Long64_t i = 0; i < nentries; i += mychain->GetTree()->GetEntries()) { | 
| 918 | for (Long64_t i = 0; i < nentries; i++) { | //          if (mychain->LoadTree(i) < 0) { | 
| 919 | if (mychain->GetEntry(i) <= 0) { | //             break; | 
| 920 | break; | //          } | 
| 921 | } | //          TTreeCloner cloner(mychain->GetTree(), newTree, option); | 
| 922 | newTree->Fill(); | //          if (cloner.IsValid()) { | 
| 923 | } | //             newTree->SetEntries(newTree->GetEntries() + mychain->GetTree()->GetEntries()); | 
| 924 | } | //             cloner.Exec(); | 
| 925 |  | //          } else { | 
| 926 | // Write the new tree header. | //             if (mychain->GetFile()) { | 
| 927 | newTree->Write(); | //            printf("Merge Skipped file %s\n", mychain->GetFile()->GetName()); | 
| 928 |  | //             //            } else { | 
| 929 | // Get our return value. | //             //               Warning("Merge", "Skipped file number %d\n", fTreeNumber); | 
| 930 | Int_t nfiles = newTree->GetFileNumber() + 1; | //             } | 
| 931 |  | //          } | 
| 932 | // Close and delete the current file of the new tree. | //       } | 
| 933 | if (!opt.Contains("keep")) { | //    } else { | 
| 934 | // FIXME: What happens to fDirectory in newTree here? | //      printf(" 33 %llu \n",nentries); | 
| 935 | delete newTree->GetCurrentFile(); | //      mychain->Print(); | 
| 936 | } | //      for (Long64_t i = 0; i < nentries; i++) { | 
| 937 | return nfiles; | //        printf(" i %llu \n",i); | 
| 938 | } | //        // for (Long64_t i = 0; i < 1; i++) { | 
| 939 |  | //          if (mychain->GetEntry(i) <= 0) { | 
| 940 |  | //             break; | 
| 941 |  | //          } | 
| 942 |  | //          newTree->Fill(); | 
| 943 |  | //       } | 
| 944 |  | //       printf(" 34 \n"); | 
| 945 |  | //    } | 
| 946 |  |  | 
| 947 |  | //    // Write the new tree header. | 
| 948 |  | //    printf(" 35 \n"); | 
| 949 |  | //    newTree->Write(); | 
| 950 |  |  | 
| 951 |  | //    printf(" 36 \n"); | 
| 952 |  | //    // Get our return value. | 
| 953 |  | //    Int_t nfiles = newTree->GetFileNumber() + 1; | 
| 954 |  |  | 
| 955 |  | //    // Close and delete the current file of the new tree. | 
| 956 |  | //    if (!opt.Contains("keep")) { | 
| 957 |  | //       // FIXME: What happens to fDirectory in newTree here? | 
| 958 |  | //       delete newTree->GetCurrentFile(); | 
| 959 |  | //    } | 
| 960 |  | //    return nfiles; | 
| 961 |  | // } |