//
#include <sstream>
//
#include <TObject.h>
#include <TSystem.h>
#include <TArrayL.h>
#include <TFile.h>
#include <TTree.h>
#include <TDirectory.h>
#include <TSQLServer.h>
#include <TSQLRow.h>
#include <TSQLResult.h>
//
#include <GLTables.h>
#include <RunInfo.h>
ClassImp(SoftInfo);
ClassImp(ItoRunInfo);
//
using namespace std;
//

SoftInfo::SoftInfo() {
  TRIG_ver = "";
  TOF_ver = "";
  AC_ver = "";
  TRK_ver = "";
  ORB_ver = "";
  CAL_ver = "";
  ND_ver = "";
  S4_ver = "";  
}

/**
 * Fills a struct cSoftInfo with values from a SoftInfo object (to put data into a F77 common).
 */
void SoftInfo::GetLevel2Struct(cSoftInfo *l2) const{
  l2->FillTrigWith(TRIG_ver);
  l2->FillTofWith(TOF_ver);
  l2->FillAcWith(AC_ver);
  l2->FillTrkWith(TRK_ver);
  l2->FillOrbWith(ORB_ver);
  l2->FillCalWith(CAL_ver);
  l2->FillNdWith(ND_ver);
  l2->FillS4With(S4_ver);
}
/***********************/

ItoRunInfo::ItoRunInfo() {
  reprocessing = false;
  updating = false;
  isreadonly = true;
  first_file_entry = 0;
  last_file_entry = 0;
  file_entries = 0ULL;
  totnorun = 0LL;
  version = new SoftInfo();
  version->TRIG_ver = "";
  version->TOF_ver = "";
  version->AC_ver = "";
  version->TRK_ver = "";
  version->CAL_ver = "";
  version->ND_ver = "";
  version->S4_ver = "";  
  version->ORB_ver = "";  
  norun = 0;
  runlist = new TArrayL(0,NULL);
  file = new TFile();
  newtree = new TTree();
}

ItoRunInfo::ItoRunInfo(TFile *processFl){
  //
  file=(TFile*)processFl;
  dbc=NULL;
  processFolder = "";
  idRun = 0ULL;
  Detector = "NONE";
  //
  reprocessing = false;
  updating = false;
  first_file_entry = 0;
  last_file_entry = 0;
  file_entries = 0ULL;
  version = new SoftInfo();
  version->TRIG_ver = "";
  version->TOF_ver = "";
  version->AC_ver = "";
  version->TRK_ver = "";
  version->ORB_ver = "";
  version->CAL_ver = "";
  version->ND_ver = "";
  version->S4_ver = "";  
  norun = 0;
  totnorun = 0;
  //  runlist = new TArrayL(0,NULL);
  //
}

ItoRunInfo::ItoRunInfo(TSQLServer *db, TFile *processFl, TString processFld){
  //
  file=(TFile*)processFl;
  dbc=(TSQLServer*)db;
  processFolder = processFld;
  //
  reprocessing = false;
  updating = false;
  first_file_entry = 0;
  last_file_entry = 0;
  file_entries = 0ULL;
  version = new SoftInfo();
  version->TRIG_ver = "";
  version->TOF_ver = "";
  version->AC_ver = "";
  version->TRK_ver = "";
  version->ORB_ver = "";
  version->CAL_ver = "";
  version->ND_ver = "";
  version->S4_ver = "";  
  norun = 0;
  totnorun = 0;
  runlist = new TArrayL(0,NULL);
  //
}

Int_t ItoRunInfo::Update(ULong64_t run, TString Detector, TString Version){
  //
  isreadonly = false;
  idRun = run;
  //
  Bool_t debug = false;
  //
  Bool_t ismydir = false;
  //
  if ( !strcmp(processFolder.Data(),"") ){
    processFolder = "runinfoFolder";
    ismydir = true;
  };
  //
  GL_RUN *oldrun = new GL_RUN();
  GL_RUN *newrun = new GL_RUN();
  SoftInfo *oldver = new SoftInfo();
  SoftInfo *newver = new SoftInfo();
  //
  ID = 0ULL;
  ID_REG_RUN = 0ULL;
  ID_REG_RUN_L2 = 0ULL;
  RUNHEADER_TIME = 0ULL;
  RUNTRAILER_TIME = 0ULL;
  EV_REG_PHYS_FROM = 0; 
  EV_REG_PHYS_TO = 0;  
  EV_REG_RUNHEADER = 0;  
  EV_REG_RUNTRAILER = 0;  
  TRK_CALIB_USED = 0;
  EFF_WRK_SCHEDULE = 0;
  PRH_VAR_TRG_MODE_A = 0;
  PRH_VAR_TRG_MODE_B = 0;
  ACQ_BUILD_INFO = 0;
  ACQ_VAR_INFO = 0; 
  version->TRIG_ver = "";
  version->TOF_ver = "";
  version->AC_ver = "";
  version->TRK_ver = "";
  version->ORB_ver = "";
  version->CAL_ver = "";
  version->ND_ver = "";
  version->S4_ver = "";  
  //
  norun = 0;
  runlist = new TArrayL(0,NULL);
  //runlist->Reset();
  //
  Bool_t found = false;
  Int_t error = 0;
  //
  //  TFile *temprfile = 0;
  //  TTree *temprrun = 0;
  //  stringstream temprname;
  //  stringstream tempdir;
  //  const char* routdir = gSystem->DirName(gSystem->DirName(file->GetPath()));
  //
  TTree *oldtree = 0;
  //
  //
  // Try to get the tree Run in the processed file
  //
  oldtree = (TTree*)file->Get("Run");  
  //
  // Look for detector's versions if we are updating a single detector
  //
  if ( debug ) printf("Detector -%s- \n",Detector.Data());
  if ( !strcmp(Detector.Data(),"NONE") ){
    version->TRIG_ver = Version;
    version->TOF_ver = Version;
    version->AC_ver = Version;
    version->TRK_ver = Version;
    version->ORB_ver = Version;
    version->CAL_ver = Version;    
    version->S4_ver = Version;
    version->ND_ver = Version;
  } else {
    if ( !strcmp(Detector.Data(),"TRIG") ) version->TRIG_ver = Version;
    if ( !strcmp(Detector.Data(),"TOF") ) version->TOF_ver = Version;
    if ( !strcmp(Detector.Data(),"AC") ) version->AC_ver = Version;
    if ( !strcmp(Detector.Data(),"TRK") ) version->TRK_ver = Version;
    if ( !strcmp(Detector.Data(),"CALO") ) version->CAL_ver = Version;
    if ( !strcmp(Detector.Data(),"S4") ) version->S4_ver = Version;
    if ( !strcmp(Detector.Data(),"ND") ) version->ND_ver = Version;
    if ( !strcmp(Detector.Data(),"ORB") ) version->ORB_ver = Version;
    if ( strcmp(Detector.Data(),"TRIG") && strcmp(Detector.Data(),"TOF") &&  strcmp(Detector.Data(),"AC") && strcmp(Detector.Data(),"TRK") &&  strcmp(Detector.Data(),"CALO") && strcmp(Detector.Data(),"S4") && strcmp(Detector.Data(),"ND") && strcmp(Detector.Data(),"ORB") ) return(-804);
  };
  //
  if ( !oldtree ) {
    //
    if ( strcmp(Detector.Data(),"NONE") ) return(-803);
    updating = false;
    if ( debug ) printf(" RunInfo: creating Run tree in this file\n");
    //
  } else {
    //
//     temprname.str("");
//     temprname << routdir;
//     temprname << "/" << processFolder.Data();
//     gSystem->MakeDirectory(temprname.str().c_str());
//     tempdir.str("");
//     tempdir << temprname.str().c_str();
//     temprname << "/runinfo_run";
//     temprname << idRun << ".root";  
//     if ( debug ) printf(" file temporaneo is %s \n",temprname.str().c_str());
//     //
//     temprfile = new TFile(temprname.str().c_str(),"RECREATE");
//     //
//     temprrun = new TTree();
//     //
//     if ( !temprfile ) return(-805);
//     if ( !oldtree ) return(-806);
//     if ( !temprrun ) return(-807);
//     //
//     temprrun = oldtree->CloneTree(-1,"fast");    
//     //
//     temprfile->cd();
//     temprrun->SetName("Run-old");
//     temprfile->Write();
//     if ( temprrun ) temprrun->Delete();
//     temprfile->Close();   
//     //
//     oldtree->Delete("all");
    //
    updating = true;
    if ( debug ) printf(" RunInfo: updating versioning information \n");
    //
  };
  //
  file->cd();
  // 
  // Prepare a new tree to upgrade the contents of the old tree 
  //
  newtree = new TTree("Run-new","PAMELA Level2 data from the GL_RUN table");
  newtree->Branch("RunInfo","GL_RUN",&newrun);
  newtree->Branch("SoftInfo","SoftInfo",&newver);
  //  
  //
  if ( !updating ){
    if ( idRun == 0ULL ){
      if ( debug ) printf("\n RUNINFO - ERROR: reprocessing data but no RunInfo tree in Level2 file. \n");
      return(-805);
    };
    //
    runlist = new TArrayL(1);
    //
    error = Query_GL_RUN(idRun, dbc);
    //
    if ( error ){
      if ( debug ) printf("\n RUNINFO - ERROR: Query_GL_RUN exited with non zero error\n");
      return(error);
    };
    if ( ID == 0ULL ){
      if ( debug ) printf("\n RUNINFO - ERROR: no run with ID_RUN = %llu \n",idRun);
      return(-5);
    };
    //
    //
    //
    newrun->ID = ID;
    newrun->ID_REG_RUN = ID_REG_RUN;
    newrun->ID_REG_RUN_L2 = ID_REG_RUN_L2;
    newrun->RUNHEADER_TIME = RUNHEADER_TIME;
    newrun->RUNTRAILER_TIME = RUNTRAILER_TIME;
    newrun->EV_REG_PHYS_FROM = EV_REG_PHYS_FROM;
    newrun->EV_REG_PHYS_TO = EV_REG_PHYS_TO;
    newrun->EV_REG_RUNHEADER = EV_REG_RUNHEADER;
    newrun->EV_REG_RUNTRAILER = EV_REG_RUNTRAILER;
    newrun->TRK_CALIB_USED = TRK_CALIB_USED;
    newrun->EFF_WRK_SCHEDULE = EFF_WRK_SCHEDULE;
    newrun->PRH_VAR_TRG_MODE_A = PRH_VAR_TRG_MODE_A;
    newrun->PRH_VAR_TRG_MODE_B = PRH_VAR_TRG_MODE_B;
    newrun->ACQ_BUILD_INFO = ACQ_BUILD_INFO;
    newrun->ACQ_VAR_INFO = ACQ_VAR_INFO;
    newver->TRIG_ver = version->TRIG_ver;
    newver->TOF_ver = version->TOF_ver;
    newver->AC_ver = version->AC_ver;
    newver->TRK_ver = version->TRK_ver;
    newver->ORB_ver = version->ORB_ver;
    newver->CAL_ver = version->CAL_ver;
    newver->S4_ver = version->S4_ver;
    newver->ND_ver = version->ND_ver;
    //
    // fill the tree;
    //
    newtree->Fill();
    //
    totnorun = 1;
    reprocessing = false;
    first_file_entry = 0;
    last_file_entry = (UInt_t)(EV_REG_PHYS_TO - EV_REG_PHYS_FROM);
    norun = 1;
    runlist->AddAt((Long64_t)ID,0);
    //
    newtree->SetName("Run");
    //
    file->cd();
    //    file->Write("Run");
    //newtree->Delete();
    delete newver;
    delete newrun;
    delete oldver;
    delete oldrun;
    //
    return(0);
    //
  } else {
    //
    //    temprfile = new TFile(temprname.str().c_str(),"READ");
    //    oldtree = (TTree*)temprfile->Get("Run-old");
    //
    oldtree->SetBranchAddress("RunInfo",&oldrun);
    oldtree->SetBranchAddress("SoftInfo",&oldver);
    //
    totnorun = oldtree->GetEntries();
    //
    runlist = new TArrayL((Int_t)totnorun);
    //
    found = false;
    //
    for ( UInt_t run = 0; run < totnorun; run++){
      //
      oldtree->GetEntry(run);
      //
      newrun->ID = oldrun->ID;
      newrun->ID_REG_RUN = oldrun->ID_REG_RUN;
      newrun->ID_REG_RUN_L2 = oldrun->ID_REG_RUN_L2;
      newrun->RUNHEADER_TIME = oldrun->RUNHEADER_TIME;
      newrun->RUNTRAILER_TIME = oldrun->RUNTRAILER_TIME;
      newrun->EV_REG_PHYS_FROM = oldrun->EV_REG_PHYS_FROM;
      newrun->EV_REG_PHYS_TO = oldrun->EV_REG_PHYS_TO;
      newrun->EV_REG_RUNHEADER = oldrun->EV_REG_RUNHEADER;
      newrun->EV_REG_RUNTRAILER = oldrun->EV_REG_RUNTRAILER;
      newrun->TRK_CALIB_USED = oldrun->TRK_CALIB_USED;
      newrun->EFF_WRK_SCHEDULE = oldrun->EFF_WRK_SCHEDULE;
      newrun->PRH_VAR_TRG_MODE_A = oldrun->PRH_VAR_TRG_MODE_A;
      newrun->PRH_VAR_TRG_MODE_B = oldrun->PRH_VAR_TRG_MODE_B;
      newrun->ACQ_BUILD_INFO = oldrun->ACQ_BUILD_INFO;
      newrun->ACQ_VAR_INFO = oldrun->ACQ_VAR_INFO;
      newver->TRIG_ver = oldver->TRIG_ver;
      newver->TOF_ver = oldver->TOF_ver;
      newver->AC_ver = oldver->AC_ver;
      newver->TRK_ver = oldver->TRK_ver;
      newver->ORB_ver = oldver->ORB_ver;
      newver->CAL_ver = oldver->CAL_ver;
      newver->S4_ver = oldver->S4_ver;
      newver->ND_ver = oldver->ND_ver;
      //
      file_entries += (oldrun->EV_REG_PHYS_TO - oldrun->EV_REG_PHYS_FROM + 1);
      //
      if ( debug ) printf("totnorun %i idRun %i newrun->ID %i \n",(int)totnorun,(int)idRun,(int)newrun->ID);
      //
      if ( idRun == 0ULL || idRun == newrun->ID ) {
	//
	if ( debug ) printf(" Updating run number %llu \n",idRun);
	//
	found = true;
	//
	runlist->AddAt(newrun->ID,norun);
	norun++;
	//
	if ( !strcmp(Detector.Data(),"NONE") ){
	  //
	  // update infromations querying the DB
	  //
	  error = Query_GL_RUN(newrun->ID, dbc);
	  //
 	  if ( error ){
 	    if ( debug ) printf("\n RUNINFO - ERROR: Query_GL_RUN exited with non zero error\n");
 	    return(error);
 	  };
	  //
	  newrun->ID = ID;
	  newrun->ID_REG_RUN = ID_REG_RUN;
	  newrun->ID_REG_RUN_L2 = ID_REG_RUN_L2;
	  newrun->RUNHEADER_TIME = RUNHEADER_TIME;
	  newrun->RUNTRAILER_TIME = RUNTRAILER_TIME;
	  newrun->EV_REG_PHYS_FROM = EV_REG_PHYS_FROM;
	  newrun->EV_REG_PHYS_TO = EV_REG_PHYS_TO;
	  newrun->EV_REG_RUNHEADER = EV_REG_RUNHEADER;
	  newrun->EV_REG_RUNTRAILER = EV_REG_RUNTRAILER;
	  newrun->TRK_CALIB_USED = TRK_CALIB_USED;
	  newrun->EFF_WRK_SCHEDULE = EFF_WRK_SCHEDULE;
	  newrun->PRH_VAR_TRG_MODE_A = PRH_VAR_TRG_MODE_A;
	  newrun->PRH_VAR_TRG_MODE_B = PRH_VAR_TRG_MODE_B;
	  newrun->ACQ_BUILD_INFO = ACQ_BUILD_INFO;
	  newrun->ACQ_VAR_INFO = ACQ_VAR_INFO;
	} else {
	  //
	  if ( !strcmp(Detector.Data(),"TRIG") ){
	    newver->TRIG_ver = version->TRIG_ver;
	    newver->TOF_ver = oldver->TOF_ver;
	    newver->AC_ver = oldver->AC_ver;
	    newver->TRK_ver = oldver->TRK_ver;
	    newver->ORB_ver = oldver->ORB_ver;
	    newver->CAL_ver = oldver->CAL_ver;
	    newver->S4_ver = oldver->S4_ver;
	    newver->ND_ver = oldver->ND_ver;
	    if ( strcmp(oldver->TRIG_ver.Data(),"") ) reprocessing = true;
	  };
	  if ( !strcmp(Detector.Data(),"TOF") ){
	    newver->TRIG_ver = oldver->TRIG_ver;
	    newver->TOF_ver = version->TOF_ver;
	    newver->AC_ver = oldver->AC_ver;
	    newver->TRK_ver = oldver->TRK_ver;
	    newver->ORB_ver = oldver->ORB_ver;
	    newver->CAL_ver = oldver->CAL_ver;
	    newver->S4_ver = oldver->S4_ver;
	    newver->ND_ver = oldver->ND_ver;
	    if ( strcmp(oldver->TOF_ver.Data(),"") ) reprocessing = true;
	  };
	  if ( !strcmp(Detector.Data(),"AC") ){
	    newver->TRIG_ver = oldver->TRIG_ver;
	    newver->TOF_ver = oldver->TOF_ver;
	    newver->TRK_ver = oldver->TRK_ver;
	    newver->ORB_ver = oldver->ORB_ver;
	    newver->CAL_ver = oldver->CAL_ver;
	    newver->S4_ver = oldver->S4_ver;
	    newver->ND_ver = oldver->ND_ver;
	    newver->AC_ver = version->AC_ver;
	    if ( strcmp(oldver->AC_ver.Data(),"") ) reprocessing = true;
	  };
	  if ( !strcmp(Detector.Data(),"TRK") ){
	    newver->TRIG_ver = oldver->TRIG_ver;
	    newver->TOF_ver = oldver->TOF_ver;
	    newver->CAL_ver = oldver->CAL_ver;
	    newver->ORB_ver = oldver->ORB_ver;
	    newver->S4_ver = oldver->S4_ver;
	    newver->ND_ver = oldver->ND_ver;
	    newver->AC_ver = oldver->AC_ver;
	    newver->TRK_ver = version->TRK_ver;
	    if ( strcmp(oldver->TRK_ver.Data(),"") ) reprocessing = true;
	  };
	  if ( !strcmp(Detector.Data(),"ORB") ){
	    newver->TRIG_ver = oldver->TRIG_ver;
	    newver->TOF_ver = oldver->TOF_ver;
	    newver->CAL_ver = oldver->CAL_ver;
	    newver->TRK_ver = oldver->TRK_ver;
	    newver->S4_ver = oldver->S4_ver;
	    newver->ND_ver = oldver->ND_ver;
	    newver->AC_ver = oldver->AC_ver;
	    newver->ORB_ver = version->ORB_ver;
	    if ( strcmp(oldver->ORB_ver.Data(),"") ) reprocessing = true;
	  };
	  if ( !strcmp(Detector.Data(),"CALO") ){
	    newver->TRIG_ver = oldver->TRIG_ver;
	    newver->TOF_ver = oldver->TOF_ver;
	    newver->S4_ver = oldver->S4_ver;
	    newver->ORB_ver = oldver->ORB_ver;
	    newver->ND_ver = oldver->ND_ver;
	    newver->AC_ver = oldver->AC_ver;
	    newver->TRK_ver = oldver->TRK_ver;
	    newver->CAL_ver = version->CAL_ver;
	    if ( strcmp(oldver->CAL_ver.Data(),"") ) reprocessing = true;
	  };	
	  if ( !strcmp(Detector.Data(),"S4") ){
	    newver->TRIG_ver = oldver->TRIG_ver;
	    newver->TOF_ver = oldver->TOF_ver;
	    newver->ND_ver = oldver->ND_ver;
	    newver->AC_ver = oldver->AC_ver;
	    newver->TRK_ver = oldver->TRK_ver;
	    newver->ORB_ver = oldver->ORB_ver;
	    newver->CAL_ver = oldver->CAL_ver;
	    newver->S4_ver = version->S4_ver;
	    if ( strcmp(oldver->S4_ver.Data(),"") ) reprocessing = true;
	  };
	  if ( !strcmp(Detector.Data(),"ND") ){
	    newver->TRIG_ver = oldver->TRIG_ver;
	    newver->TOF_ver = oldver->TOF_ver;
	    newver->S4_ver = oldver->S4_ver;
	    newver->AC_ver = oldver->AC_ver;
	    newver->ORB_ver = oldver->ORB_ver;
	    newver->TRK_ver = oldver->TRK_ver;
	    newver->CAL_ver = oldver->CAL_ver;
	    newver->ND_ver = version->ND_ver;
	    if ( strcmp(oldver->ND_ver.Data(),"") ) reprocessing = true;
	  };
	};
	//
	last_file_entry = first_file_entry + (oldrun->EV_REG_PHYS_TO - oldrun->EV_REG_PHYS_FROM + 1);
	//
      } else {
	if ( !found ) first_file_entry += (oldrun->EV_REG_PHYS_TO - oldrun->EV_REG_PHYS_FROM + 1);
      };
      //
      file->cd();
      newtree->Fill();
      //
    };
    //
    //    temprfile->Close();
    //    gSystem->Unlink(temprname.str().c_str());
    //    if ( ismydir ) gSystem->Unlink(tempdir.str().c_str());
    file->cd();
    if ( oldtree ) oldtree->Delete("all");
    newtree->SetName("Run");
    //    file->Write("Run");
    //    newtree->Delete();
    delete newver;
    delete newrun;
    delete oldver;
    delete oldrun;
    //
    if ( !found ){
      if ( debug ) printf("\n RUNINFO - ERROR: no run with ID_RUN = %llu \n",idRun);
      return(-5);
    };
    //
    //    newtree->Write();
  };
  return(0);
}

Int_t ItoRunInfo::Read(ULong64_t idRun){
  //
  isreadonly = true;
  //
  Bool_t debug = false;
  //
  SoftInfo *newver = new SoftInfo();
  GL_RUN *newrun = new GL_RUN();
  //
  // Try to get the tree Run in the processed file
  //
  newtree = (TTree*)file->Get("Run");  
  // 
  if ( !newtree ) {
    //
    printf("\n RUNINFO - ERROR: no RunInfo tree in Level2 file. \n");
    return(-801);
    //
  } else {
    //
    printf(" RunInfo: opening RunInfo tree \n");
    //
    newtree->SetBranchAddress("RunInfo",&newrun);
    newtree->SetBranchAddress("SoftInfo",&newver);
    //
    totnorun = newtree->GetEntries();
    //
    runlist = new TArrayL((Int_t)totnorun);
    //
    first_file_entry = 0;
    //
    for ( UInt_t run = 0; run < totnorun; run++){
      //
      newtree->GetEntry(run);
      //
      file_entries += (newrun->EV_REG_PHYS_TO - newrun->EV_REG_PHYS_FROM + 1);
      //
      if ( debug ) printf("totnorun %i  newrun->ID %i \n",(int)totnorun,(int)newrun->ID);
      //
      ID = newrun->ID;
      ID_REG_RUN = newrun->ID_REG_RUN;
      ID_REG_RUN_L2 = newrun->ID_REG_RUN_L2;
      RUNHEADER_TIME = newrun->RUNHEADER_TIME;
      RUNTRAILER_TIME = newrun->RUNTRAILER_TIME;
      EV_REG_PHYS_FROM = newrun->EV_REG_PHYS_FROM;
      EV_REG_PHYS_TO = newrun->EV_REG_PHYS_TO;
      EV_REG_RUNHEADER = newrun->EV_REG_RUNHEADER;
      EV_REG_RUNTRAILER = newrun->EV_REG_RUNTRAILER;
      TRK_CALIB_USED = newrun->TRK_CALIB_USED;
      EFF_WRK_SCHEDULE = newrun->EFF_WRK_SCHEDULE;
      PRH_VAR_TRG_MODE_A = newrun->PRH_VAR_TRG_MODE_A;
      PRH_VAR_TRG_MODE_B = newrun->PRH_VAR_TRG_MODE_B;
      ACQ_BUILD_INFO = newrun->ACQ_BUILD_INFO;
      ACQ_VAR_INFO = newrun->ACQ_VAR_INFO;
      version->TRIG_ver = newver->TRIG_ver;
      version->TOF_ver = newver->TOF_ver;
      version->AC_ver = newver->AC_ver;
      version->TRK_ver = newver->TRK_ver;
      version->ORB_ver = newver->ORB_ver;
      version->CAL_ver = newver->CAL_ver;
      version->S4_ver = newver->S4_ver;
      version->ND_ver = newver->ND_ver;
      if ( idRun == ID || idRun == 0ULL ){
	runlist->AddAt(newrun->ID,norun);
	norun++;
      };
      last_file_entry = first_file_entry + (newrun->EV_REG_PHYS_TO - newrun->EV_REG_PHYS_FROM + 1);
    };
  };
  if ( debug ) printf("norun %i \n",(int)norun);
  Int_t error = 0;
  error = GetRunInfo(idRun);
  delete newver;
  delete newrun;
  if ( error ) return(error);
  return(0);
}    

void ItoRunInfo::Close(){
  reprocessing = false;
  updating = false;
  first_file_entry = 0;
  last_file_entry = 0;
  file_entries = 0ULL;
  norun = 0;
  runlist = new TArrayL(0,NULL);
  file = new TFile();  
  if ( isreadonly ) newtree->Delete();
}

void ItoRunInfo::Clear(){
  if ( newtree ) newtree->Delete();
}

UInt_t ItoRunInfo::GetRunForEntry(UInt_t entry){
  //
  UInt_t startfrom = 0;
  //
  if ( entry >= (UInt_t)first_file_entry && entry <= (UInt_t)last_file_entry ) return(ID);
  //
  if ( entry > (UInt_t)last_file_entry ){
    for ( UInt_t nrun = 0; nrun < norun; nrun++){  
      if ( ID == (ULong64_t)runlist->At(nrun) ) {
	startfrom = nrun+1;
	break;
      };
    };
  } else {
    startfrom = 0;
  };
  //
  if ( startfrom >= norun ) startfrom = 0;
  //
 retry:
  //
  for ( UInt_t nrun = startfrom; nrun < norun; nrun++){  
    GetRunInfo((ULong64_t)runlist->At(nrun));
    if ( entry >= (UInt_t)first_file_entry && entry <= (UInt_t)last_file_entry ){
      return((UInt_t)runlist->At(nrun));
    };
  };
  if ( startfrom ){
    startfrom = 0;
    goto retry;
  };
  printf(" ERROR! run not found \n");
  return(0);
}

Int_t ItoRunInfo::GetRunInfo(ULong64_t run){
  Bool_t found = false;
  SoftInfo *nwver = new SoftInfo();
  GL_RUN *nwrun = new GL_RUN();
  //
  newtree->SetBranchAddress("RunInfo",&nwrun);
  newtree->SetBranchAddress("SoftInfo",&nwver);
  //
  last_file_entry = 0;
  first_file_entry = 0;
  //
  totnorun = newtree->GetEntries();
  //
  for ( UInt_t nrun = 0; nrun < totnorun; nrun++){  
    newtree->GetEntry(nrun);
    //
    if ( nwrun->ID == run || run == 0ULL ){
      ID = nwrun->ID;
      ID_REG_RUN = nwrun->ID_REG_RUN;
      ID_REG_RUN_L2 = nwrun->ID_REG_RUN_L2;
      RUNHEADER_TIME = nwrun->RUNHEADER_TIME;
      RUNTRAILER_TIME = nwrun->RUNTRAILER_TIME;
      EV_REG_PHYS_FROM = nwrun->EV_REG_PHYS_FROM;
      EV_REG_PHYS_TO = nwrun->EV_REG_PHYS_TO;
      EV_REG_RUNHEADER = nwrun->EV_REG_RUNHEADER;
      EV_REG_RUNTRAILER = nwrun->EV_REG_RUNTRAILER;
      TRK_CALIB_USED = nwrun->TRK_CALIB_USED;
      EFF_WRK_SCHEDULE = nwrun->EFF_WRK_SCHEDULE;
      PRH_VAR_TRG_MODE_A = nwrun->PRH_VAR_TRG_MODE_A;
      PRH_VAR_TRG_MODE_B = nwrun->PRH_VAR_TRG_MODE_B;
      ACQ_BUILD_INFO = nwrun->ACQ_BUILD_INFO;
      ACQ_VAR_INFO = nwrun->ACQ_VAR_INFO;
      version->TRIG_ver = nwver->TRIG_ver;
      version->TOF_ver = nwver->TOF_ver;
      version->AC_ver = nwver->AC_ver;
      version->TRK_ver = nwver->TRK_ver;
      version->ORB_ver = nwver->ORB_ver;
      version->CAL_ver = nwver->CAL_ver;
      version->S4_ver = nwver->S4_ver;
      version->ND_ver = nwver->ND_ver;
      found = true;
      last_file_entry = first_file_entry + (nwrun->EV_REG_PHYS_TO - nwrun->EV_REG_PHYS_FROM + 1);
    };
    if ( !found ) first_file_entry += (nwrun->EV_REG_PHYS_TO - nwrun->EV_REG_PHYS_FROM + 1);
  };
  delete nwver;
  delete nwrun;
  if ( found ) return(0);
  return(-800);
}

