//
#include <iomanip>
#include <sstream>
//
#include <iostream>
#include <string>
#include <fstream>
#include <list>
#include <errno.h>
//
#include <TFile.h>
#include <TSystem.h>
#include <TSQLResult.h>
#include <TSQLRow.h>
#include <TTree.h>
#include <TGraph.h>
#include <TTimeStamp.h>
#include <TF1.h>
//
#include <EventHeader.h>
#include <PscuHeader.h>
#include <mcmd/McmdEvent.h>
#include <mcmd/McmdRecord.h>
#include <RunHeaderEvent.h>
#include <RunTrailerEvent.h>
#include <CalibCalPedEvent.h>
#include <CalibCalPulse1Event.h>
#include <CalibCalPulse2Event.h>
#include <CalibS4Event.h>
#include <CalibTrk1Event.h>
#include <CalibTrk2Event.h>
#include <varDump/VarDumpEvent.h>
#include <varDump/VarDumpRecord.h>
#include <physics/S4/S4Event.h>
//
#include <sgp4.h>

#include <PamelaDBOperations.h>
//
using namespace std;
using namespace pamela;

// Some function to work with cTle stuff.
bool compTLE(cTle* tle1, cTle *tle2);
float getTleJulian(cTle *);
string getTleDatetime(cTle*);

/**
 * Constructor.
 * @param host         hostname for the SQL connection.
 * @param user         username for the SQL connection.
 * @param password     password for the SQL connection.
 * @param filerawname  The path and name to the raw file.
 * @param filerootname The path and name of the raw file.
 * @param boot         file BOOT number.
 * @param obt0         file obt0.
 * @param tsync        file timesync.
 * @param debug        debug flag.
 * @param tlefilename  ascii file with TLE 3 line elements.
 */
PamelaDBOperations::PamelaDBOperations(TString host, TString user, TString password, TString filerawname, TString filerootname, UInt_t boot, UInt_t tsync, UInt_t obt0, Bool_t debug, TString tlefilename, UInt_t dwinput, Bool_t staticp, Bool_t gpamela, Bool_t keepenv){
  //
  RELAXED = false;
  chewbacca = false;
  chminentry = 0;
  chID = 0;
  if ( filerootname.IsDigit() ){
    if ( debug ) printf(" => using database to process the file \n");
    chewbacca = true;
    chID = (UInt_t)filerootname.Atoll();
    //
    // are these really necessary?
    //
    staticp = false;
    INSERT_RAW = false;
    dwinput = 1;
    //
  };
  //
  KEEPENV = false;
  if ( keepenv ) KEEPENV=true;
  STATIC=false;
  if ( staticp ) STATIC=true;
  //
  SetConnection(host,user,password);
  //
  SetDebugFlag(debug);
  //
  glrun = new GL_RUN();
  //
  //   if ( !chewbacca ){
  //     if ( !boot ) SetNOBOOT(false);
  //     SetTsync(tsync,gpamela);
  //     SetBOOTnumber(boot,gpamela);
  //     SetObt0(obt0);
  //   };
  //
  SetTLEPath(tlefilename);
  //
  //
  if ( !chewbacca ) INSERT_RAW =!filerawname.IsNull();
  if (INSERT_RAW) SetRawName(filerawname);
  //
  INSERT_ROOT = !filerootname.IsNull();
  if ( INSERT_ROOT ) this->SetRootName(filerootname);
  this->SetOrbitNo(dwinput);
  //
  this->SetID_RAW(0);
  this->SetID_ROOT(0);

  VALIDATE = false;
  
  //
};

/**
 * Destructor
 */
void PamelaDBOperations::Close(){
  if( conn && conn->IsConnected() ) conn->Close();
  delete clean_time;
  delete glrun;
  delete this;
};

//
// SETTERS 
//
void PamelaDBOperations::NotChewbacca(UInt_t boot, UInt_t tsync, UInt_t obt0, Bool_t gpamela){
  if ( !boot ) SetNOBOOT(false);
  SetTsync(tsync,gpamela);
  SetBOOTnumber(boot,gpamela);
  SetObt0(obt0);
};

void PamelaDBOperations::OpenL0File(TString filerootname){
  if( INSERT_ROOT ){
    if ( chewbacca ){
      //
      // retrieve from the ROOT_TABLE the chewbacca path and filename
      //           
      stringstream qu;
      TSQLResult *result = 0;
      TSQLResult *result2 = 0;
      TSQLResult *result3 = 0;
      TSQLRow    *row    = 0;    
      TSQLRow    *row2    = 0;    
      TSQLRow    *row3    = 0;    
      TString chpath;
      TString chfile;
      UInt_t ridn = 0;
      qu.str("");
      qu << "SELECT ROOT_ID_N,PKT_NUMBER_INIT,PKT_NUMBER_FINAL,PKT_OBT_INIT,PKT_OBT_FINAL,INSERTED_BY,REAL_TIME_INIT from ROOT_TABLE_MERGING where ID_N=" << chID << ";"; 
      if ( debug ) printf(" chewbacca: query is %s \n",qu.str().c_str());
      result = conn->Query(qu.str().c_str());
      if ( result ){
	row = result->Next();
	if ( row ){
	  ridn = (UInt_t)atoll(row->GetField(0));
	  chpktmin = (UInt_t)atoll(row->GetField(1));
	  chpktmax = (UInt_t)atoll(row->GetField(2));
	  chobtmin = (UInt_t)atoll(row->GetField(3));
	  chobtmax = (UInt_t)atoll(row->GetField(4));
	  chiby = (TString)(row->GetField(5));
	  chrtinit = (UInt_t)atoll(row->GetField(6));
	} else {
	  throw -84;
	};
      } else {
	throw -84;
      };
      delete result;
      qu.str("");
      qu << "SELECT FOLDER_NAME,FILE_NAME,OBT_TIME_SYNC,LAST_TIME_SYNC_INFO,TIME_OFFSET,BOOT_NUMBER,PKT_NUMBER_INIT,PKT_NUMBER_FINAL,PKT_OBT_INIT,PKT_OBT_FINAL,REAL_TIME_INIT from ROOT_TABLE where ID_N=" << ridn << ";"; 
      if ( debug ) printf(" chewbacca: query is %s \n",qu.str().c_str());
      result2 = conn->Query(qu.str().c_str());
      if ( result2 ){
	row2 = result2->Next();
	if ( row2 ){
	  if ( KEEPENV ){
	    chpath = (TString)(row2->GetField(0))+'/';
	  } else {
	    chpath = (TString)gSystem->ExpandPathName(row2->GetField(0))+'/';
	  };
	  chfile = (TString)(row2->GetField(1));
	  chobtts = (UInt_t)atoll(row2->GetField(2));
	  chlastts = (UInt_t)atoll(row2->GetField(3));
	  chresursts = (UInt_t)atoll(row2->GetField(4));
	  chboot = (UInt_t)atoll(row2->GetField(5));
	  //
	  if ( !chboot ){
	    if ( debug ) printf(" mmm... no BOOT number determined by chewbacca, try to find it looking at DB \n");
	    //
	    // new feature: check in ROOT_TABLE (timewise) the previous and the next BOOT number != 0 , if it is the same we know this one!
	    // if it is different roll back to the old behaviour
	    // 
	    qu.str("");
	    qu << "SELECT BOOT_NUMBER from ROOT_TABLE where BOOT_NUMBER!=0 AND REAL_TIME_INIT>"<< row2->GetField(10) <<" order by REAL_TIME_INIT asc limit 1;"; 
	    if ( debug ) printf(" chewbacca: query is %s \n",qu.str().c_str());
	    UInt_t chbootA = 0;
	    UInt_t chbootB = 1;
	    result3 = conn->Query(qu.str().c_str());
	    if ( result3 ){
	      row3 = result3->Next();
	      if ( row3 ){
		chbootA = (UInt_t)atoll(row3->GetField(0));
		if ( debug ) printf(" Found boot_number A = %u \n",chbootA);
	      };
	    };
	    delete result3;
	    qu.str("");
	    qu << "SELECT BOOT_NUMBER from ROOT_TABLE where BOOT_NUMBER!=0 AND REAL_TIME_INIT<"<< row2->GetField(10) <<" order by REAL_TIME_INIT desc limit 1;"; 
	    if ( debug ) printf(" chewbacca: query is %s \n",qu.str().c_str());
	    result3 = conn->Query(qu.str().c_str());
	    if ( result3 ){
	      row3 = result3->Next();
	      if ( row3 ){
		chbootB = (UInt_t)atoll(row3->GetField(0));
		if ( debug ) printf(" Found boot_number B = %u \n",chbootB);
	      };
	    };
	    if ( chbootA == chbootB ){
	      chboot = chbootA;
	      if ( debug ) printf(" Found boot_number! it is %u \n",chboot);
	    } else {	    
	      qu.str("");
	      //	    qu << "SELECT BOOT_NUMBER from ROOT_TABLE where BOOT_NUMBER!=0 AND ABS(LAST_TIME_SYNC_INFO-"<< chlastts <<")<10000 AND ABS(REAL_TIME_INIT-"<< row2->GetField(10) <<")<7200 group by BOOT_NUMBER order by BOOT_NUMBER asc;"; 
	      //	    qu << "SELECT BOOT_NUMBER from ROOT_TABLE where BOOT_NUMBER!=0 AND ABS(LAST_TIME_SYNC_INFO-"<< chlastts <<")<40000 AND ABS(REAL_TIME_INIT-"<< row2->GetField(10) <<")<40000 group by BOOT_NUMBER order by BOOT_NUMBER asc;"; // relax conditions... 090112 [8RED: error -29]
	      qu << "SELECT BOOT_NUMBER from ROOT_TABLE where BOOT_NUMBER!=0 AND ABS(LAST_TIME_SYNC_INFO-"<< (float)chlastts <<")<50000 AND ABS(REAL_TIME_INIT-"<< atof(row2->GetField(10)) <<")<50000 group by BOOT_NUMBER order by BOOT_NUMBER asc;"; // even more relaxed conditions... 091214 [9REDtest3: error -29] // 10RED MYSQL operators BUG:
              /*

mysql> select CAST(1322000646 AS UNSIGNED INTEGER)-1322017203.;
+--------------------------------------------------+
| CAST(1322000646 AS UNSIGNED INTEGER)-1322017203. |
+--------------------------------------------------+
|                                           -16557 | 
+--------------------------------------------------+
1 row in set (0.06 sec)

mysql> select CAST(1322000646 AS UNSIGNED INTEGER)-1322017203;
+-------------------------------------------------+
| CAST(1322000646 AS UNSIGNED INTEGER)-1322017203 |
+-------------------------------------------------+
|                            18446744073709535059 | 
+-------------------------------------------------+
1 row in set (0.02 sec)

              */
	      if ( debug ) printf(" chewbacca: query is %s \n",qu.str().c_str());
	      result3 = conn->Query(qu.str().c_str());
	      if ( result3 ){
		row3 = result3->Next();
		if ( row3 && result3->GetRowCount() == 1 ){
		  chboot = (UInt_t)atoll(row3->GetField(0));
		  if ( debug ) printf(" Found boot_number = %u \n",chboot);
		} else {
		  if ( debug ) printf(" AGH CANNOT DETERMINE THE BOOT NUMBER... \n");
		  throw -29;
		};
	      };
	    };
	  };
	  //
	  chpktinit = (UInt_t)atoll(row2->GetField(6));
	  chpktfinal = (UInt_t)atoll(row2->GetField(7));
	  chobtinit = (UInt_t)atoll(row2->GetField(8));
	  chobtfinal = (UInt_t)atoll(row2->GetField(9));
	  //
	} else {
	  throw -85;
	};
      } else {
	throw -85;
      };
      filerootname = chpath + chfile;// + ".root";
    };
    this->SetRootName(filerootname);
  };
  if ( debug ) printf(" Filename is %s \n",filerootname.Data());
  file = TFile::Open(this->GetRootName().Data());
  //  } else {
  //    this->SetRootName("");
  //    this->SetRootName(filerootname);
  //  };
}

//
// must be out of the constructor in order to FORCE the validation of the latest runs in case you run the validation together with the latest file
//
void PamelaDBOperations::CheckValidate(Long64_t olderthan){
  clean_time = new TDatime();
  //
  if(olderthan >= 0){
    VALIDATE = true;
    UInt_t timelim = 0;
    timelim =  (UInt_t)clean_time->Convert(true) - olderthan;
    clean_time->Set(timelim,false);
  };
};

/**
 * Open the DB connection
 * @param host         hostname for the SQL connection.
 * @param user         username for the SQL connection.
 * @param password     password for the SQL connection.
 */
void PamelaDBOperations::SetConnection(TString host, TString user, TString password){
  if ( IsDebug() ) printf(" Connecting using host = %s user = %s password = %s \n",host.Data(),user.Data(),password.Data());
  conn = TSQLServer::Connect(host.Data(),user.Data(),password.Data());
};

/**
 * Store the ID of the ROOT file.
 * @param idr    ID of the ROOT file
 */
void PamelaDBOperations::SetID_ROOT(UInt_t idr){
  idroot=idr;
};

/**
 * Store the ID of the RAW file.
 * @param idr    ID of the RAW file
 */
void PamelaDBOperations::SetID_RAW(UInt_t idr){
  id=idr;
};

/**
 * Set the debug flag
 * 
 */
void PamelaDBOperations::SetDebugFlag(Bool_t dbg){
  debug = dbg;
};

/**
 * Set the autoboot flag
 * 
 */
void PamelaDBOperations::SetAutoBoot(Bool_t dbg){
  AUTOBOOT = dbg;
};

/**
 * Set the pedantic flag
 * 
 */
void PamelaDBOperations::SetPedantic(Bool_t dbg){
  PEDANTIC = dbg;
};

/**
 * Set the nofrag flag
 * 
 */
void PamelaDBOperations::SetNoFrag(Bool_t nf){
  NOFRAG = nf;
};

/**
 * Store the BOOT number of the RAW file.
 * @param boot    BOOT number of the RAW file
 */
void PamelaDBOperations::SetBOOTnumber(UInt_t boot){
  this->SetBOOTnumber(boot,false);
};

/**
 * Store the BOOT number of the RAW file.
 * @param boot    BOOT number of the RAW file
 */
void PamelaDBOperations::SetBOOTnumber(UInt_t boot, Bool_t gpamela){
  BOOTNO=boot;
  if ( gpamela ){
    stringstream oss;
    TSQLResult *result = 0;
    TSQLRow    *row    = 0;    
    if ( !boot ){
      //
      BOOTNO = 1;
      //
      // look in the DB for the last timesync and the last run 
      //
      oss.str("");
      oss << "SELECT BOOT_NUMBER FROM GL_RUN order by RUNHEADER_TIME desc limit 1;";
      result = conn->Query(oss.str().c_str());
      if ( result ){
	row = result->Next();
	if ( row ){
	  BOOTNO = (UInt_t)atoll(row->GetField(0)) + 1;
	};
      };
    };
  };
};

/**
 * Store the time sync of the RAW file.
 * @param boot    time sync
 */
void PamelaDBOperations::SetTsync(UInt_t ts){
  this->SetTsync(ts,false);
};

/**
 * Store the time sync of the RAW file.
 * @param boot    time sync
 */
void PamelaDBOperations::SetTsync(UInt_t ts, Bool_t gpamela){
  //
  // if not gpamela or given tsync file set ts
  //
  tsync=ts;
  if ( gpamela ){
    stringstream oss;
    TSQLResult *result = 0;
    TSQLRow    *row    = 0;    
    TSQLResult *result2 = 0;
    TSQLRow    *row2    = 0;    
    if ( !ts ){
      //
      tsync = 1;
      //
      // look in the DB for the last timesync and the last run 
      //
      oss.str("");
      oss << "SELECT TIMESYNC FROM GL_TIMESYNC order by TIMESYNC desc limit 1;";
      result = conn->Query(oss.str().c_str());
      if ( result ){
	row = result->Next();
	if ( row ){
	  tsync = (UInt_t)atoll(row->GetField(0)) + 1;
	  oss.str("");
	  oss << "SELECT (RUNTRAILER_TIME-RUNHEADER_TIME) FROM GL_RUN order by RUNHEADER_TIME desc limit 1;";
	  result2 = conn->Query(oss.str().c_str());
	  if ( result2 ){
	    row2 = result2->Next();
	    if ( row2 ){
	      tsync += (UInt_t)atoll(row2->GetField(0));
	    };
	  }
	};
      };
    };
  };
};

/**
 * Store the time sync of the RAW file.
 * @param boot    time sync
 */
void PamelaDBOperations::SetObt0(UInt_t ts){
  obt0=ts;
};

/**
 * Store the RAW filename.
 * @param str    the RAW filename.
 */
void PamelaDBOperations::SetRawName(TString str){
  filerawname=str;
};

/**
 * Store the ROOT filename.
 * @param str    the ROOT filename.
 */
void PamelaDBOperations::SetRootName(TString str){
  filerootname=str;
};

/**
 * Store the downlink orbit number from filename.
 */
void PamelaDBOperations::SetOrbitNo(UInt_t dwinput){
  dworbit = 0;
  //
  if ( dwinput ){
    dworbit = dwinput;
    if ( IsDebug() && !chewbacca ) printf(" Downlink orbit given by hand: %i  \n",dworbit);
    return;
  };
  //
  if ( !chewbacca ){
    TString name = this->GetRootFile();
    Int_t nlength = name.Length();
    if ( nlength < 5 ){
      if ( IsDebug() ) printf(" Agh problems determining the orbit number! name = %s \n",name.Data());
      return;
    };
    TString dwo = "";
    for (Int_t i = 0; i<5; i++){
      dwo.Append(name[i],1);
    };
    if ( dwo.IsDigit() ){
      dworbit = (UInt_t)dwo.Atoi();
    } else {
      dwo="";
      for (Int_t i = 8; i<13; i++){
	dwo.Append(name[i],1);
      };     
      if ( dwo.IsDigit() ) dworbit = (UInt_t)dwo.Atoi();
    };
    if ( IsDebug() ) printf(" Downlink orbit is %i (dwo = %s) \n",dworbit,dwo.Data());
  };
  return;
};



/**
 * Store the NOBOOT flag.
 * @param noboot    true/false.
 */
void PamelaDBOperations::SetNOBOOT(Bool_t noboot){
  NOBOOT = noboot;
};

/**
 * Store path to the TLE file.
 */
void PamelaDBOperations::SetTLEPath(TString str){
  tlefilename = str;
};

TString PamelaDBOperations::GetRawPath(){
  if ( STATIC ){
    return((TString)gSystem->DirName(filerawname.Data())+'/');
  } else {
    return((TString)gSystem->ExpandPathName("$PAM_RAW")+'/');
  };
};

TString PamelaDBOperations::GetRootPath(){
  if ( STATIC ){
    return((TString)gSystem->DirName(this->GetRootName().Data())+'/');
  } else {    
    if ( KEEPENV ){
      return((TString)gSystem->ExpandPathName(gSystem->DirName(filerootname.Data()))+'/');
    } else {
      return((TString)gSystem->ExpandPathName("$PAM_L0")+'/');
    };
  };
};

/**
 * Store the olderthan variable
 * @param olderthan
 */
// void PamelaDBOperations::SetOlderThan(Long64_t oldthan){
//   olderthan = oldthan;
// };

/**
 * Retrieve the ID_RAW, if exists, returns NULL if does not exist.
 */
Bool_t PamelaDBOperations::SetID_RAW(){
  stringstream oss;
  TSQLResult *result = 0;
  TSQLRow    *row    = 0;
  oss.str("");
  if ( STATIC ){
    oss << "SELECT ID FROM GL_RAW WHERE "
	<< " PATH = '" << this->GetRawPath().Data() << "' AND "
	<< " NAME = '" << this->GetRawFile().Data() << "' ";  
  } else {
    oss << "SELECT ID FROM GL_RAW WHERE "
	<< " PATH = '$PAM_RAW' AND "
	<< " NAME = '" << this->GetRawFile().Data() << "' ";  
  }
  result = conn->Query(oss.str().c_str());
  if ( result == NULL ) throw -4;
  row = result->Next();
  if ( !row ) return(false);
  id = (UInt_t)atoll(row->GetField(0));
  delete result;
  return(true);
}

/**
 * 
 * Set the variables which have to be stored in the GL_RUN table and that do not depend on the RUN
 * 
 */
void PamelaDBOperations::SetCommonGLRUN(UInt_t absth, UInt_t abstt){ 
  glrun->SetBOOTNUMBER(BOOTNO);
  glrun->SetRUNHEADER_TIME(absth);
  glrun->SetRUNTRAILER_TIME(abstt);
  glrun->SetID_ROOT_L2(0);
  glrun->SetID_ROOT_L0(idroot);
  glrun->SetVALIDATION(0);
};

/**
 * 
 * Set the variables which belogns to physendrun tree
 * 
 */
void PamelaDBOperations::SetPhysEndRunVariables(){ 
  //
  //
  //
  TTree *T = 0;
  T = (TTree*)file->Get("PhysEndRun");
  if ( !T || T->IsZombie() ) throw -90;
  //
  PhysEndRunEvent *pher= 0;
  EventHeader *eh = 0;
  T->SetBranchAddress("PhysEndRun", &pher); 
  T->SetBranchAddress("Header", &eh);
  //
  UInt_t phobt = 0;
  UInt_t phpkt = 0;
  //
  glrun->SetPHYSENDRUN_MASK_S3S2S12(0);
  glrun->SetPHYSENDRUN_MASK_S11CRC(0); 
  //
  for (Int_t p=0; p<T->GetEntries(); p++){
    //
    T->GetEntry(p);
    //
    phobt = (UInt_t)eh->GetPscuHeader()->GetOrbitalTime();
    phpkt = (UInt_t)eh->GetPscuHeader()->GetCounter();
    //
    if ( this->PKT(phpkt) >= this->PKT(glrun->GetRUNHEADER_PKT()) && this->PKT(phpkt) <= this->PKT(glrun->GetRUNTRAILER_PKT()) && this->OBT(phobt) >= this->OBT(glrun->GetRUNHEADER_OBT()) && this->OBT(phobt) <= this->OBT(glrun->GetRUNTRAILER_OBT())  ){
      if ( glrun->GetPHYSENDRUN_MASK_S3S2S12() || glrun->GetPHYSENDRUN_MASK_S11CRC() ){
	if ( IsDebug() ) printf(" WARNING while looping in physendrun: found two PhysEndRun packet for the same RUN! \n");
	if ( IsDebug() ) printf(" Actual values: %X %X New values %X %X \n ",glrun->GetPHYSENDRUN_MASK_S3S2S12(),glrun->GetPHYSENDRUN_MASK_S11CRC(),(UInt_t)pher->TB_ENDRUN.TB_PMT_MASK_S3S2S12,(UInt_t)pher->TB_ENDRUN.TB_PMT_MASK_S11CRC);
	if ( PEDANTIC && IsDebug() ) printf(" ERROR while looping in physendrun: found two PhysEndRun packet for the same RUN!\n ");
	if ( PEDANTIC ) throw -91;
      } else {
	glrun->SetPHYSENDRUN_MASK_S3S2S12((UInt_t)pher->TB_ENDRUN.TB_PMT_MASK_S3S2S12);
	glrun->SetPHYSENDRUN_MASK_S11CRC((UInt_t)pher->TB_ENDRUN.TB_PMT_MASK_S11CRC);
      };
    };
  };
  //
};

/**
 * Patch, look for upper limits to avoid processing retransmitted data
 */
Int_t PamelaDBOperations::SetUpperLimits(){
  UInt_t nevent = 0;
  UInt_t pktlast = 0;
  UInt_t obtlast = 0;
  Long64_t t_pktlast = 0LL;
  //  UInt_t t_obtlast = 0;
  Long64_t t_obtlast = 0LL;
  Long64_t upperpkt2 = 0LL;
  Long64_t upperobt2 = 0LL;
  UInt_t zomp = 0;
  UInt_t jump = 50000; // was 5000
  EventCounter *code=0;
  //
  Long64_t deltapkt = 5000LL;
  Long64_t deltaobt = 50000LL;
  //
  pcksList packetsNames;
  pcksList::iterator Iter;
  getPacketsNames(packetsNames);
  //
  pktfirst = 0;
  obtfirst = 0;
  ppktfirst = 0;
  pobtfirst = 0;
  //
  //
  //
  TTree *T = 0;
  T = (TTree*)file->Get("Physics");
  if ( !T || T->IsZombie() ) throw -16;
  EventHeader *eh = 0;
  PscuHeader *ph = 0;
  T->SetBranchAddress("Header", &eh);
  nevent = T->GetEntries();
  //
  T->GetEntry(0);
  ph = eh->GetPscuHeader();

  if ( chewbacca ){
    if ( IsDebug() ) printf(" FROM CHEWBACCA: upperpkt %u upperobt %u lowerpkt %u lowerobt %u \n",chpktmax,chobtmax,chpktmin,chobtmin);
    ppktfirst = chpktmin;
    pobtfirst = chobtts*1000; 
  } else {
    //
    pktfirst = ph->GetCounter();
    obtfirst = ph->GetOrbitalTime();  
    ppktfirst = pktfirst;
    pobtfirst = obtfirst; // to be changed AFTER time sync determination this is a profiler bug!
  };
  //
  code = eh->GetCounter();
  UInt_t en = 0;
  //  if ( !chewbacca ){
  for(Iter = packetsNames.begin(); Iter != packetsNames.end(); Iter++){
    en = code->Get(GetPacketType(*Iter));
    if ( !strcmp("CalibCalPed",*Iter) || !strcmp("CalibTrk1",*Iter) || !strcmp("CalibTrk2",*Iter) || !strcmp("CalibS4",*Iter) ){      
      if ( IsDebug() ) printf(" We have a calibration before the first physic packet: packet type is %s, entries: %i \n",*Iter,en);
      //
      TTree *TC = 0;
      TC = (TTree*)file->Get("CalibCalPed");
      if ( !TC || TC->IsZombie() ) throw -16;
      EventHeader *ehc = 0;
      PscuHeader *phc = 0;
      TC->SetBranchAddress("Header", &ehc);
      TC->GetEntry(0);
      phc = ehc->GetPscuHeader();
      pktfirst = phc->GetCounter();
      obtfirst = phc->GetOrbitalTime();  
      //
    };
  };  
  //
  T->GetEntry(nevent-1);
  ph = eh->GetPscuHeader();
  pktlast = ph->GetCounter();
  obtlast = ph->GetOrbitalTime();  
  //
  // paranoid check
  //
  if ( chewbacca ) {
    //
    // query the ROOT_TABLE to find upper and lower limits of the file and compare them to the given interval
    //
    if ( IsDebug() ) printf(" Is good if \n");
    if ( IsDebug() ) printf("PKT(chpktfinal) >= PKT(chpktmax) && PKT(chpktinit) <= PKT(chpktmin) && OBT(chobtfinal) >= OBT(chobtmax) && OBT(chobtinit) <= OBT(chobtmin) \n");
    if ( IsDebug() ) printf(" %llu >= %llu && %llu <= %llu && %llu >= %llu && %llu <= %llu \n",PKT(chpktfinal),PKT(chpktmax),PKT(chpktinit),PKT(chpktmin),OBT(chobtfinal),OBT(chobtmax),OBT(chobtinit),OBT(chobtmin));
    if ( PKT(chpktfinal) >= PKT(chpktmax) && PKT(chpktinit) <= PKT(chpktmin) && OBT(chobtfinal) >= OBT(chobtmax) && OBT(chobtinit) <= OBT(chobtmin) ){
      if ( IsDebug() ) printf(" OK, the file contains the chewbacca interval\n");
    } else {
      if ( IsDebug() ) printf(" Bah, the file seems to be the wrong one, the chewbacca interval is not contained in the file... is the DB correctly filled??\n");
      if ( PEDANTIC ) throw -89;
    };
  };
  //
  nrtbef = 0;
  nrtaf = 0;
  nrtbef = 0;
  nrtaf = 0;
  //
  if ( chewbacca ){
    pktfirst = chpktmin;
    obtfirst = chobtmin; 
    pktlast = chpktmax;
    obtlast = chobtmax;
    upperpkt = PKT(chpktmax);
    upperobt = OBT(chobtmax);
    pktlast = numeric_limits<UInt_t>::max();
    Int_t it = 0;
    UInt_t tjump = 50000;
    //UInt_t tjump = 100;
    while ( tjump > 0 ){
      //      pktlast = numeric_limits<UInt_t>::max();
      pktlast = chpktmax + 1;
      while ( PKT(pktlast) > PKT(chpktmax) && (Int_t)(nevent-1-it) >= 0 ){
	if ( (Int_t)(nevent-1-it) >= 0 ){
	  T->GetEntry(nevent-1-it);
	  ph = eh->GetPscuHeader();
	  pktlast = ph->GetCounter();
	} else {
	  pktlast = chpktmax + 1;
	};
	if ( (!(it%1000) || abs((int)(PKT(pktlast) - PKT(chpktmax)))<1000 ) && debug ) printf(" look for up %i %i %i nevent %u (nevent-1-it) %i \n",it,pktlast,chpktmax,nevent,(Int_t)(nevent-1-it));
	it += tjump;
      };
      if ( tjump > 1 ) it -= 2*tjump;
      if ( it < 0 ) it = 0;
      //
      if ( debug ) printf(" - look for up %i %i %i nevent %u (nevent-1-it) %i \n",it,pktlast,chpktmax,nevent,(Int_t)(nevent-1-it));
      if ( debug ) printf(" - up , tjump was %u it was %u \n",tjump,it);
      if ( tjump == 1 ) tjump = 0;
      if ( tjump == 10 ) tjump = 1;
      if ( tjump == 100 ) tjump = 10;
      if ( tjump == 1000 ) tjump = 100;
      if ( tjump == 5000 ) tjump = 1000;
      if ( tjump == 50000 ) tjump = 5000;
      //
    };
    Int_t tupperentry = (Int_t)nevent-1-(Int_t)it+1;//+1+1;
    if ( tupperentry < 0 ) tupperentry = 0; 
    upperentry = tupperentry;
    it = 0;
    pktlast = 0;
    tjump = 50000;
    //tjump = 100;
    while ( tjump > 0 ){
      //      pktlast = 0;
      pktlast = chpktmin - 1;
      if ( debug ) printf("LLlook for down %i %i %llu %llu \n",it,pktlast,PKT(pktlast),PKT(chpktmin));
      while ( PKT(pktlast) < PKT(chpktmin) && it < (Int_t)nevent ){
	if ( it < (Int_t)nevent ){ 
	  T->GetEntry(it);
	  ph = eh->GetPscuHeader();
	  pktlast = ph->GetCounter();
	} else {
	  //	  pktlast = chpktmax - 1;
	  pktlast = chpktmin - 1;
	};
	if ( !(it%1000) && debug ) printf("look for down %i %i %i \n",it,pktlast,chpktmin);
	it += tjump;
      };
      if ( tjump > 1 ) it -= 2*tjump;
      if ( it < 0 ) it = 0;
      //
      if ( debug ) printf(" down , tjump was %u it was %u \n",tjump,it);
      if ( tjump == 1 ) tjump = 0;
      if ( tjump == 10 ) tjump = 1;
      if ( tjump == 100 ) tjump = 10;
      if ( tjump == 1000 ) tjump = 100;
      if ( tjump == 5000 ) tjump = 1000;
      if ( tjump == 50000 ) tjump = 5000;
      //
    };
    Int_t tchminentry = (Int_t)it-1;//-1+1;
    if ( tchminentry < 0 ) tchminentry = 0;
    chminentry = tchminentry;
    //
    if ( debug ) printf(" Chewbacca: chminentry %i chmaxentry %i delta %i nevent %i \n",chminentry,upperentry,upperentry-chminentry,nevent);
    //
    //
    //
    TTree *rh=(TTree*)file->Get("RunHeader");
    if ( !rh || rh->IsZombie() ) throw -17;
    TTree *rt=(TTree*)file->Get("RunTrailer");
    if ( !rt || rt->IsZombie() ) throw -18;
    //
    rh->SetBranchAddress("RunHeader", &runh);
    rh->SetBranchAddress("Header", &ehh);
    //
    rt->SetBranchAddress("RunTrailer", &runt);
    rt->SetBranchAddress("Header", &eht);
    //
    rhev = rh->GetEntries();
    rtev = rt->GetEntries();
    //
    if ( IsDebug() ){
      for (Int_t rr=0; rr<rh->GetEntries(); rr++){
	rh->GetEntry(rr); 
	phh = ehh->GetPscuHeader();
	printf(" RUNHEADER %i OBT %u PKT %u \n",rr,phh->GetOrbitalTime(),phh->GetCounter());
      };
      for (Int_t rr=0; rr<rt->GetEntries(); rr++){
	rt->GetEntry(rr);
	pht = eht->GetPscuHeader();
	printf(" RUNTRAILER %i OBT %u PKT %u \n",rr,pht->GetOrbitalTime(),pht->GetCounter());
      };
    };
    //
    nrhev = 0;
    nrhbef = 0;
    nrhaf = 0;
    for (Int_t rr=0; rr<rh->GetEntries(); rr++){
      rh->GetEntry(rr);
      phh = ehh->GetPscuHeader();
      if ( debug ) printf(" RRRRRRR %llu %llu %llu %llu %llu %llu \n",PKT(phh->GetCounter()),PKT(pktfirst),upperpkt,OBT(obtfirst),OBT(phh->GetOrbitalTime()),upperobt);
      if ( PKT(phh->GetCounter()) >= PKT(pktfirst) && PKT(phh->GetCounter()) <= upperpkt && OBT(phh->GetOrbitalTime()) >= OBT(obtfirst) && OBT(phh->GetOrbitalTime()) <= upperobt ){
	nrhev++;
	if ( debug ) printf(" ++++ RH %i \n",nrhev);
      };
      if ( !nrhev ) nrhbef++;
      if ( (nrhev && (nrhev+1+nrhbef+1) == rr) || nrhaf ) nrhaf++;
    };
    nrtev = 0;
    nrtbef = 0;
    nrtaf = 0;
    for (Int_t rr=0; rr<rt->GetEntries(); rr++){
      rt->GetEntry(rr);
      pht = eht->GetPscuHeader();
      if ( debug ) printf(" TTTTTTT %llu %llu %llu %llu %llu %llu \n",PKT(pht->GetCounter()),PKT(pktfirst),upperpkt,OBT(obtfirst),OBT(pht->GetOrbitalTime()),upperobt);
      if ( PKT(pht->GetCounter()) >= PKT(pktfirst) && PKT(pht->GetCounter()) <= upperpkt && OBT(pht->GetOrbitalTime()) >= OBT(obtfirst) && OBT(pht->GetOrbitalTime()) <= upperobt ){
	nrtev++;
	if ( debug ) printf(" ++++ RT %i \n",nrtev);
      };
      if ( !nrtev ) nrtbef++;
      if ( (nrtev && (nrtev+1+nrtbef+1) == rr) || nrtaf ) nrtaf++;
    };
    if ( debug ) printf(" NUMBER OF RH %i RT %i IN THE INTERVAL, NUMBER OF TOTAL RH %i RT %i \n",nrhev,nrtev,rhev,rtev);
    if ( debug ) printf(" RH before %i RH after %i -- RT before %i RT after %i \n",nrhbef,nrhaf,nrtbef,nrtaf);
    //    
    T->GetEntry(upperentry);
    ph = eh->GetPscuHeader();
    pktlast = ph->GetCounter();
    nevent = upperentry - chminentry;
    if ( ((Int_t)upperentry - (Int_t)chminentry) < 0 ) nevent = 0; // nevent is UInt_t! 090112 [8RED: error -88]
    if ( IsDebug() ) printf(" Setting nevent to %u - upperentry %i chminentry %i \n",nevent,upperentry,chminentry);
    //
  } else {
    upperpkt = PKT(pktlast);
    upperobt = OBT(obtlast);
    upperentry = nevent-1;
  };
  //
  if ( chewbacca && nevent < 1 ) {
    if ( IsDebug() ) printf(" chewbacca and no events in the file \n");
    pktfirst = chpktmin;
    upperpkt = PKT(chpktmax);
    pktlast = chpktmax;
    obtfirst = chobtmin;
    obtlast = chobtmax;
    upperobt = OBT(chobtmax);
  };
  //
  if ( IsDebug() ) printf(" First entries are: OBT %u pkt_num %u entry %i\n",obtfirst,pktfirst,chminentry); 
  //
  if ( IsDebug() ) printf(" Last entries are: OBT %lld pkt_num %lld entry %i\n",upperobt,upperpkt,upperentry); 
  //
  if ( (PKT(pktlast) < PKT(pktfirst) && OBT(obtlast) > OBT(obtfirst)) || (PKT(pktlast) > PKT(pktfirst) && OBT(obtlast) < OBT(obtfirst)) ){
    if ( IsDebug() ) printf(" Inconsistent PKT/OBT sequence: \n     (PKT(pktlast) < PKT(pktfirst) && OBT(obtlast) > OBT(obtfirst)) %llu < %llu && %llu > %llu \n     OR \n     (PKT(pktlast) > PKT(pktfirst) && OBT(obtlast) < OBT(obtfirst)) %llu > %llu && %llu < %llu \n",PKT(pktlast),PKT(pktfirst),OBT(obtlast),OBT(obtfirst),PKT(pktlast),PKT(pktfirst),OBT(obtlast),OBT(obtfirst)); 
    if ( PEDANTIC ) throw -88;
    return(32);
  };
  //
  if ( !nevent ) return(64);
  //
  if ( nevent < 2 ) return(128);
  if ( nevent < jump ) jump = 1;
  //  if ( nevent < jump ) jump = int(nevent/10);
  //  if ( !jump ) jump = 1;
  //

  if ( ((PKT(pktlast) < PKT(pktfirst) && OBT(obtlast) < OBT(obtfirst)) || (labs(PKT(pktlast)-PKT(pktfirst))<deltapkt && labs(OBT(obtlast)-OBT(obtfirst))<deltaobt)) && nevent > deltapkt ){
    //
    if ( IsDebug() ) printf(" starting jump %i \n",jump);
    //    if ( IsDebug() ) printf(" (PKT(pktlast) < PKT(pktfirst) && OBT(obtlast) > OBT(obtfirst)) %llu < %llu && %llu > %llu \n     OR \n     (PKT(pktlast) > PKT(pktfirst) && OBT(obtlast) < OBT(obtfirst)) %llu > %llu && %llu < %llu \n",PKT(pktlast),PKT(pktfirst),OBT(obtlast),OBT(obtfirst),PKT(pktlast),PKT(pktfirst),OBT(obtlast),OBT(obtfirst)); 
    if ( IsDebug() ) printf(" labs(PKT(pktlast)-PKT(pktfirst) %lu < deltapkt %lld && labs(OBT(obtlast)-OBT(obtfirst)) %lu <deltaobt %lld && nevent %u > deltapkt %lld \n",(labs(PKT(pktlast)-PKT(pktfirst))),deltapkt, labs(OBT(obtlast)-OBT(obtfirst)),deltaobt, nevent, deltapkt);
    if ( PEDANTIC ) throw -66;
    // go back
    zomp = nevent - 2;
    //
    while ( jump > 0 ){
      //
      t_pktlast = PKT(pktlast);
      t_obtlast = OBT(obtlast);    
      //
      for (UInt_t i = zomp; i>1; i-=jump){  
	//
	if ( i >= 0 ) T->GetEntry(i);
	ph = eh->GetPscuHeader();
	upperpkt = PKT(ph->GetCounter());
	upperobt = OBT(ph->GetOrbitalTime());
	upperentry = i;
	//
	if ( (i-1) >= 0 ) T->GetEntry(i-1);
	ph = eh->GetPscuHeader();
	upperpkt2 = PKT(ph->GetCounter());
	upperobt2 = OBT(ph->GetOrbitalTime());
	//
	if ( (t_pktlast < upperpkt && t_obtlast > upperobt) || (t_pktlast < upperpkt2 && t_obtlast > upperobt2) ){
	  if ( IsDebug() ) printf(" .-. upperpkt2 %lld upperobt2 %lld \n",upperpkt2,upperobt2);	  
	  if ( IsDebug() ) printf(" .-. upperpkt %lld t_pktlast %lld upperobt %lld t_obtlast %lld \n",upperpkt,t_pktlast,upperobt,t_obtlast);	  
	  if ( IsDebug() ) printf(" .-. jump %i zomp %i upperpkt %lld pktlast %u upperobt %lld obtlast %u last entry is %i \n",jump,zomp,upperpkt,pktlast,upperobt,obtlast,i);	  
	  throw -13;	
	};
	//
	if ( t_pktlast < upperpkt && t_obtlast < upperobt && t_pktlast < upperpkt2 && t_obtlast < upperobt2 ){
	  zomp = i + jump + 1;
	  if ( zomp > nevent-2 ) zomp = nevent - 2;
	  if ( IsDebug() ) printf(" .-. jump %i zomp %i upperpkt %lld pktlast %u upperobt %lld obtlast %u last entry is %i \n",jump,zomp,upperpkt,pktlast,upperobt,obtlast,i);
	  break;
	};
	//
	t_pktlast = upperpkt;
	t_obtlast = upperobt;
      };    
      //
      if ( jump == 1 ) jump = 0;
      if ( jump == 10 ) jump = 1;
      if ( jump == 100 ) jump = 10;
      if ( jump == 1000 ) jump = 100;
      if ( jump == 5000 ) jump = 1000;
      if ( jump == 50000 ) jump = 5000;
      //
    };
    //
  };
  //
  // check if last runtrailer is within limits, if not extend limits (one should check for all packets but we need only runtrailer)
  //
  if ( !chewbacca ){
    PacketType *pctp=0;
    TTree *rh=(TTree*)file->Get("RunHeader");
    if ( !rh || rh->IsZombie() ) throw -17;
    TTree *rt=(TTree*)file->Get("RunTrailer");
    if ( !rt || rt->IsZombie() ) throw -18;
    //
    rh->SetBranchAddress("RunHeader", &runh);
    rh->SetBranchAddress("Header", &ehh);
    //
    rt->SetBranchAddress("RunTrailer", &runt);
    rt->SetBranchAddress("Header", &eht);
    //
    rhev = rh->GetEntries();
    rtev = rt->GetEntries();
    Long64_t sobtt = 0LL;
    Long64_t sobth = 0LL;
    Long64_t spktt = 0LL;
    Long64_t spkth = 0LL;
    Long64_t pktt = 0LL;
    Long64_t obtt = 0LL;
    Long64_t pkth = 0LL;
    Long64_t obth = 0LL;
    //
    if ( rhev || rtev ){
      
      T->GetEntry(upperentry);
      code = eh->GetCounter();
      Int_t lasttrail = code->Get(pctp->RunTrailer);
      Int_t lasthead = code->Get(pctp->RunHeader);
      if ( lasttrail < rtev ){
	rt->GetEntry(lasttrail);
	pht = eht->GetPscuHeader();
	pktt = PKT(pht->GetCounter());
	obtt = OBT(pht->GetOrbitalTime());
      };
      //
      if ( lasthead < rhev ){
	rh->GetEntry(lasthead);
	phh = ehh->GetPscuHeader();
	pkth = PKT(phh->GetCounter());
	obth = OBT(phh->GetOrbitalTime());
      };
      //
      if ( IsDebug() ) printf(" rhev before %i ph %lld upperp %lld oh %lld uppero %lld \n",rhev,pkth,upperpkt,obth,upperobt);
      if ( pkth > upperpkt && obth > upperobt ){
	if ( IsDebug() ) printf(" Upper limits extended to include last header: ph %lld upperp %lld oh %lld uppero %lld \n",pkth,upperpkt,obth,upperobt);
	upperpkt = pkth;
	upperobt = obth;
	rhev = lasthead+1;
      } else {
	rhev = lasthead;
      };
      if ( IsDebug() ) printf(" rhev after %i ph %lld upperp %lld oh %lld uppero %lld \n",rhev,pkth,upperpkt,obth,upperobt);
      //
      if ( IsDebug() ) printf(" rtev beforev %i  pt %lld upperp %lld ot %lld uppero %lld \n",rtev,pktt,upperpkt,obtt,upperobt);
      if ( pktt > upperpkt && obtt > upperobt ){
	if ( IsDebug() ) printf(" Upper limits extended to include last trailer: pt %lld upperp %lld ot %lld uppero %lld \n",pktt,upperpkt,obtt,upperobt);
	upperpkt = pktt;
	upperobt = obtt;
	rtev = lasttrail+1;
      } else {
	rtev = lasttrail;
      };
      if ( IsDebug() ) printf(" rtev after %i  pt %lld upperp %lld ot %lld uppero %lld \n",rtev,pktt,upperpkt,obtt,upperobt);
      //  goto kikko;
      //
      // 
      // Check if runtrailer/runheader are within lower limits
      //
      //
      pkth = 0LL;
      obth = 0LL;
      spkth = 0LL;
      sobth = 0LL;
      for (Int_t k=0; k<rhev; k++){
	if ( k > 0 ){
	  spkth = pkth;
	  sobth = obth;
	};
	rh->GetEntry(k);
	phh = ehh->GetPscuHeader();
	pkth = PKT(phh->GetCounter());
	obth = OBT(phh->GetOrbitalTime());
	//
	//    if ( IsDebug() ) printf(" k %i rhev before %i ph %u upperp %u oh %u uppero %u \n",k,rhev,pkth,spkth,obth,sobth);
	//
	if ( pkth < spkth && obth < sobth ){
	  if ( IsDebug() ) printf(" RH PROBLEMS determining the event repetition at the end of the file lasthead %i  \n",rhev);
	  if ( PEDANTIC ) throw -66;
	  //
	  rhev = k-1;
	  rh->GetEntry(rhev);
	  pkth = spkth;
	  obth = sobth;
	  //
	  UInt_t evbefh = 0;
	  code = ehh->GetCounter();
	  evbefh = code->Get(pctp->Physics);    
	  if ( evbefh >= 0 ){
	    T->GetEntry(evbefh);
	    ph = eh->GetPscuHeader();
	    t_pktlast = PKT(ph->GetCounter());
	    t_obtlast = OBT(ph->GetOrbitalTime());
	    if ( t_pktlast <= spkth && t_obtlast <= sobth ){ // jump
	      upperpkt = pkth;
	      upperobt = obth;
	      upperentry = evbefh-1;
	    } else {
	      while ( t_pktlast > spkth && t_obtlast > sobth && evbefh < nevent ){
		evbefh++;	
		T->GetEntry(evbefh);
		ph = eh->GetPscuHeader();
		t_pktlast = PKT(ph->GetCounter());
		t_obtlast = OBT(ph->GetOrbitalTime());
	      };
	      T->GetEntry(evbefh-1);
	      ph = eh->GetPscuHeader();
	      upperpkt = PKT(ph->GetCounter());
	      upperobt = OBT(ph->GetOrbitalTime());
	      upperentry = evbefh-1;
	    };    
	  };
	  if ( IsDebug() ) printf(" rhev after %i ph %lld upperp %lld oh %lld uppero %lld \n",rhev,pkth,upperpkt,obth,upperobt);
	  goto kikko0;
	};
      };
    kikko0:
      //
      //
      //
      pktt = 0LL;
      obtt = 0LL;
      spktt = 0LL;
      sobtt = 0LL;
      for (Int_t k=0; k<rtev; k++){
	if ( k > 0 ){
	  spktt = pktt;
	  sobtt = obtt;
	};
	rt->GetEntry(k);
	pht = eht->GetPscuHeader();
	pktt = PKT(pht->GetCounter());
	obtt = OBT(pht->GetOrbitalTime());
	//
	//    if ( IsDebug() ) printf(" k %i rtev beforev %i  pt %i upperp %i ot %llu uppero %llu \n",k,rtev,pktt,spktt,obtt,sobtt);
	//
	if ( pktt < spktt && obtt < sobtt ){
	  if ( IsDebug() ) printf(" RT PROBLEMS determining the event repetition at the end of the file lasttrail %i \n",rtev);
	  if ( PEDANTIC ) throw -66;
	  //
	  rtev = k-1;
	  rt->GetEntry(rtev);
	  pktt = spktt;
	  obtt = sobtt;
	  if ( IsDebug() ) printf(" lasttrail %i pt %lld upperp %lld ot %lld uppero %lld \n",rtev,pktt,upperpkt,obtt,upperobt);
	  //
	  UInt_t evbeft = 0;
	  code = eht->GetCounter();
	  evbeft = code->Get(pctp->Physics);    
	  if ( evbeft >= 0 ){
	    T->GetEntry(evbeft);
	    ph = eh->GetPscuHeader();
	    t_pktlast = PKT(ph->GetCounter());
	    t_obtlast = OBT(ph->GetOrbitalTime());
	    if ( t_pktlast <= spktt && t_obtlast <= sobtt ){ // jump
	      upperpkt = pktt;
	      upperobt = obtt;
	      upperentry = evbeft-1;
	    } else {
	      while ( t_pktlast > spktt && t_obtlast > sobtt && evbeft < nevent ){
		evbeft++;	
		T->GetEntry(evbeft);
		ph = eh->GetPscuHeader();
		t_pktlast = PKT(ph->GetCounter());
		t_obtlast = OBT(ph->GetOrbitalTime());
	      };
	      T->GetEntry(evbeft-1);
	      ph = eh->GetPscuHeader();
	      upperpkt = PKT(ph->GetCounter());
	      upperobt = OBT(ph->GetOrbitalTime());
	      upperentry = evbeft-1;
	    };
	  };
	  if ( IsDebug() ) printf(" rtev after %i  pt %lld upperp %lld ot %lld uppero %lld \n",rtev,pktt,upperpkt,obtt,upperobt);
	  goto kikko;
	  //      break;
	  //
	};
	//  
      };
      //
    kikko:
      //
      T->GetEntry(upperentry);
      code = eh->GetCounter();
      lasttrail = code->Get(pctp->RunTrailer);
      lasthead = code->Get(pctp->RunHeader);
      if ( lasttrail < rtev ){
	rt->GetEntry(lasttrail);
	pht = eht->GetPscuHeader();
	pktt = PKT(pht->GetCounter());
	obtt = OBT(pht->GetOrbitalTime());
      };
      //
      if ( lasthead < rhev ){
	rh->GetEntry(lasthead);
	phh = ehh->GetPscuHeader();
	pkth = PKT(phh->GetCounter());
	obth = OBT(phh->GetOrbitalTime());
      };
      //
      if ( IsDebug() ) printf(" rhev before %i ph %lld upperp %lld oh %lld uppero %lld \n",rhev,pkth,upperpkt,obth,upperobt);
      if ( pkth > upperpkt && obth > upperobt ){
	if ( IsDebug() ) printf(" Upper limits extended to include last header: ph %lld upperp %lld oh %lld uppero %lld \n",pkth,upperpkt,obth,upperobt);
	upperpkt = pkth;
	upperobt = obth;
	rhev = lasthead+1;
      } else {
	rhev = lasthead;
      };
      if ( IsDebug() ) printf(" rhev after %i ph %lld upperp %lld oh %lld uppero %lld \n",rhev,pkth,upperpkt,obth,upperobt);
      //
      if ( IsDebug() ) printf(" rtev beforev %i  pt %lld upperp %lld ot %lld uppero %lld \n",rtev,pktt,upperpkt,obtt,upperobt);
      if ( pktt > upperpkt && obtt > upperobt ){
	if ( IsDebug() ) printf(" Upper limits extended to include last trailer: pt %lld upperp %lld ot %lld uppero %lld \n",pktt,upperpkt,obtt,upperobt);
	upperpkt = pktt;
	upperobt = obtt;
	rtev = lasttrail+1;
      } else {
	rtev = lasttrail;
      };
      if ( IsDebug() ) printf(" rtev after %i  pt %lld upperp %lld ot %lld uppero %lld \n",rtev,pktt,upperpkt,obtt,upperobt);
      //
    };
  };
  //
  if ( IsDebug() ) printf(" Upper limits are: OBT %lld pkt_num %lld upper entry %i \n",upperobt,upperpkt,upperentry); 
  //
  return(0);
}

/**
 *
 * Trick to have unique RUN ID numbers even when runs are deleted and mysql deamon restarted.
 * Entries in the _RUNID_GEN table are never deleted.
 *
 **/
UInt_t PamelaDBOperations::AssignRunID(){
  //
  TSQLResult *result = 0;
  TSQLRow *row = 0;
  UInt_t runid = 0;
  //
  stringstream   oss;
  //  
  oss.str("");
  if ( chewbacca ){// if chewbacca and tag=none then use chewbacca tag (chiby = chewbacca inserted by), if chewbacca and tag!=none then use tag, if not chewbacca use tag.
    if ( !strcmp(tag.Data(),"NONE") ){
      oss << "INSERT INTO _RUNID_GEN VALUES (NULL,'"<< chiby.Data() <<"');";
    } else {
      oss << "INSERT INTO _RUNID_GEN VALUES (NULL,'"<< tag.Data() <<"');";
    };
  } else {
    oss << "INSERT INTO _RUNID_GEN VALUES (NULL,'"<< tag.Data() <<"');";
  };
  result = conn->Query(oss.str().c_str());
  if ( !result ) throw -10;
  oss.str("");
  oss << "SELECT ID FROM _RUNID_GEN ORDER BY ID DESC LIMIT 1;";
  result = conn->Query(oss.str().c_str());
  if ( !result ) throw -10;
  //
  row = result->Next();
  //
  if ( !row ) throw -28;
  //
  runid = (UInt_t)atoll(row->GetField(0));
  //
  return(runid);
};

//
// GETTERS
//

/**
 * 
 * Returns the DB absolute time needed to associate calibrations to data
 * 
 */
UInt_t PamelaDBOperations::GetAbsTime(UInt_t obt){  
  //
  return(((UInt_t)(OBT(obt)/1000)+toffset));
  //
};

/**
 * 
 *  List of packet types (just to make easily the loops)
 *
 */
const PacketType* PamelaDBOperations::GetPacketType(const char* type){
  if ( !strcmp(type,"Pscu") ) return(PacketType::Pscu);  
  if ( !strcmp(type,"PhysEndRun") ) return(PacketType::PhysEndRun);
  if ( !strcmp(type,"CalibCalPulse1") ) return(PacketType::CalibCalPulse1);
  if ( !strcmp(type,"CalibCalPulse2") ) return(PacketType::CalibCalPulse2);
  if ( !strcmp(type,"Physics") ) return(PacketType::Physics);
  if ( !strcmp(type,"CalibTrkBoth") ) return(PacketType::CalibTrkBoth);
  if ( !strcmp(type,"CalibTrk1") ) return(PacketType::CalibTrk1);
  if ( !strcmp(type,"CalibTrk2") ) return(PacketType::CalibTrk2);
  if ( !strcmp(type,"CalibTof") ) return(PacketType::CalibTof);
  if ( !strcmp(type,"CalibS4") ) return(PacketType::CalibS4);
  if ( !strcmp(type,"CalibCalPed") ) return(PacketType::CalibCalPed);
  if ( !strcmp(type,"Calib1_Ac1") ) return(PacketType::Calib1_Ac1);
  if ( !strcmp(type,"Calib2_Ac1") ) return(PacketType::Calib2_Ac1);
  if ( !strcmp(type,"Calib1_Ac2") ) return(PacketType::Calib1_Ac2);
  if ( !strcmp(type,"Calib2_Ac2") ) return(PacketType::Calib2_Ac2);
  if ( !strcmp(type,"CalibCal") ) return(PacketType::CalibCal);
  if ( !strcmp(type,"RunHeader") ) return(PacketType::RunHeader);
  if ( !strcmp(type,"RunTrailer") ) return(PacketType::RunTrailer);
  if ( !strcmp(type,"CalibHeader") ) return(PacketType::CalibHeader);
  if ( !strcmp(type,"CalibTrailer") ) return(PacketType::CalibTrailer);
  if ( !strcmp(type,"InitHeader") ) return(PacketType::InitHeader);
  if ( !strcmp(type,"InitTrailer") ) return(PacketType::InitTrailer);
  if ( !strcmp(type,"EventTrk") ) return(PacketType::EventTrk);
  if ( !strcmp(type,"Log") ) return(PacketType::Log);
  if ( !strcmp(type,"VarDump") ) return(PacketType::VarDump);
  if ( !strcmp(type,"ArrDump") ) return(PacketType::ArrDump);
  if ( !strcmp(type,"TabDump") ) return(PacketType::TabDump);
  if ( !strcmp(type,"Tmtc") ) return(PacketType::Tmtc);
  if ( !strcmp(type,"Mcmd") ) return(PacketType::Mcmd);
  if ( !strcmp(type,"ForcedFECmd") ) return(PacketType::ForcedFECmd);
  if ( !strcmp(type,"Ac1Init") ) return(PacketType::Ac1Init);
  if ( !strcmp(type,"CalInit") ) return(PacketType::CalInit);
  if ( !strcmp(type,"TrkInit") ) return(PacketType::TrkInit);
  if ( !strcmp(type,"TofInit") ) return(PacketType::TofInit);
  if ( !strcmp(type,"TrgInit") ) return(PacketType::TrgInit);
  if ( !strcmp(type,"NdInit") ) return(PacketType::NdInit);
  if ( !strcmp(type,"S4Init") ) return(PacketType::S4Init);
  if ( !strcmp(type,"Ac2Init") ) return(PacketType::Ac2Init);
  if ( !strcmp(type,"CalAlarm") ) return(PacketType::CalAlarm);
  if ( !strcmp(type,"Ac1Alarm") ) return(PacketType::Ac1Alarm);
  if ( !strcmp(type,"TrkAlarm") ) return(PacketType::TrkAlarm);
  if ( !strcmp(type,"TrgAlarm") ) return(PacketType::TrgAlarm);
  if ( !strcmp(type,"TofAlarm") ) return(PacketType::TofAlarm);
  if ( !strcmp(type,"S4Alarm") ) return(PacketType::S4Alarm);
  if ( !strcmp(type,"Ac2Alarm") ) return(PacketType::Ac2Alarm);
  if ( !strcmp(type,"TsbT") ) return(PacketType::TsbT);
  if ( !strcmp(type,"TsbB") ) return(PacketType::TsbB);
  return(PacketType::Invalid);
};

//
// PRIVATE FUNCTIONS 
//

// /**
// * Open the ROOT filename for reading
// */
// void PamelaDBOperations::OpenFile(){
//   file = TFile::Open(this->GetRootName().Data());
//   //

void PamelaDBOperations::CheckFile(){  
  if ( !file ) throw -12;
};


/**
 * Check if LEVEL0 file and DB connection have really be opened
 */
void PamelaDBOperations::CheckConnection(){  
  //
  // check connection
  //
  if( !conn ) throw -1;
  bool connect = conn->IsConnected();
  if( !connect ) throw -1;
  //
  if ( IsDebug() ) printf("\n DB INFORMATIONS:\n SQL: %s Version: %s Host %s Port %i \n\n",conn->GetDBMS(),conn->ServerInfo(),conn->GetHost(),conn->GetPort());
  //
  if ( !dworbit && strcmp(this->GetRootName().Data(),"") ) throw -27;
  //
  // set DB timezone to UTC
  //
  stringstream oss;
  //  
  oss.str("");
  oss << "SET time_zone='+0:00';";
  TSQLResult *result = 0;
  result = conn->Query(oss.str().c_str()); 
  if ( !result ) throw -10;
  oss.str("");
  oss << "SET wait_timeout=173000;";
  conn->Query(oss.str().c_str()); 
  delete conn->Query("SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';");
  //
}

/**
 * Lock tables
 */
void PamelaDBOperations::LockTables(){  
  //
  // check connection
  //
  if( !conn ) throw -1;
  bool connect = conn->IsConnected();
  if( !connect ) throw -1;
  //
  stringstream oss;
  //  
  oss.str("");
  oss << "lock table GL_RUN write, GL_ROOT write, GL_RAW write, GL_TIMESYNC write, GL_RESURS_OFFSET write, GL_PARAM write, GL_TLE write, GL_RUN_FRAGMENTS write, GL_RUN_TRASH write, GL_CALO_CALIB write, GL_CALOPULSE_CALIB write, GL_TRK_CALIB write, GL_S4_CALIB write, ROOT_TABLE_MERGING write, ROOT_TABLE_BAD write, ROOT_TABLE write, _RUNID_GEN write;";
  TSQLResult *result = 0;
  result = conn->Query(oss.str().c_str()); 
  if ( !result ) throw -10;
  //
}

/**
 * Lock tables
 */
void PamelaDBOperations::UnLockTables(){  
  //
  // check connection
  //
  if( !conn ) throw -1;
  bool connect = conn->IsConnected();
  if( !connect ) throw -1;
  //
  stringstream oss;
  //  
  oss.str("");
  oss << "unlock tables;";
  TSQLResult *result = 0;
  result = conn->Query(oss.str().c_str()); 
  if ( !result ) throw -10;
  //
}

/**
 * Return the correct packet number if we went back to zero
 */
Long64_t PamelaDBOperations::PKT(UInt_t pkt_num){  
  //
  //  if ( IsDebug() ) printf(" pkt conversion: pkt_num is %u pktfirst is %u  (UInt_t)(16777214/2)) is %u  \n",pkt_num,ppktfirst,(UInt_t)(16777214/2));
  //
  if ( pkt_num < (ppktfirst/2) && ppktfirst > (16777214/2)  ){
    //    if ( IsDebug() ) printf(" rise up pktnum %lld \n",(Long64_t)pkt_num+16777215LL);
    return((Long64_t)pkt_num+16777215LL);
  };
  //
  if ( pkt_num > ((Long64_t)ppktfirst*2) && pkt_num > (16777214/2) ){
    //    if ( IsDebug() ) printf(" rise down pktnum %lld \n",(Long64_t)pkt_num-16777215LL);
    return((Long64_t)pkt_num-16777215LL);
  };
  //
  //  if ( IsDebug() ) printf(" as it is %lld \n",(Long64_t)pkt_num);
  return((Long64_t)pkt_num);
  //
};

/**
 * Return the correct On Board Time if we went back to zero
 */
Long64_t PamelaDBOperations::OBT(UInt_t obt){  
  //
  //  if ( IsDebug() ) printf(" obt conversion: obt is %u obtfirst is %u  (numeric_limits<UInt_t>::max()/2) is %u  \n",obt,pobtfirst,(UInt_t)(numeric_limits<UInt_t>::max()/2));
  //
  if ( obt < ((Long64_t)pobtfirst/2) && pobtfirst > (numeric_limits<UInt_t>::max()/2) ){
    //    if ( IsDebug() ) printf(" rise up obt %lld \n",(Long64_t)obt+(Long64_t)numeric_limits<UInt_t>::max());
    return((Long64_t)obt+(Long64_t)numeric_limits<UInt_t>::max());
  };
  //
  if ( obt > ((Long64_t)pobtfirst*2) && obt > (numeric_limits<UInt_t>::max()/2) ){
    //    if ( IsDebug() ) printf(" pobtfirst*2 %lld \n",((Long64_t)pobtfirst*2));
    //    if ( IsDebug() ) printf(" rise down pktnum %lld \n", (Long64_t)obt-(Long64_t)numeric_limits<UInt_t>::max());
    return((Long64_t)obt-(Long64_t)numeric_limits<UInt_t>::max());
  };
  //
  //  if ( IsDebug() ) printf(" as it is %lld \n",(Long64_t)obt);
  return((Long64_t)obt);
};

/**
 * 
 *  Fill the glrun class with infos about the run when we have both runtrailer and runheader
 * 
 */
void PamelaDBOperations::FillClass(){
  this->FillClass(false,false,-1,-1);
};

/**
 * 
 *  Fill the glrun class with infos about the run when we have both runtrailer and runheader
 * 
 */
void PamelaDBOperations::FillClass(Bool_t mishead, Bool_t mistrail, Int_t firstev, Int_t lastev){
  //
  TTree *T = 0;
  T = (TTree*)file->Get("Physics");
  if ( !T || T->IsZombie() ) throw -16;
  //
  EventHeader *eh = 0;
  PscuHeader *ph = 0;
  T->SetBranchAddress("Header", &eh);
  PacketType *pctp=0;
  EventCounter *codt=0;
  EventCounter *codh=0;
  UInt_t firstObt = 0;
  UInt_t lastObt = 0;
  UInt_t firstPkt = 0;
  UInt_t lastPkt = 0;
  UInt_t rhtime = 0;
  UInt_t rttime = 0;
  //
  if ( IsDebug() ) printf(" A firstev %i lastev %i nevents %i \n",firstev,lastev,lastev-firstev+1);
  //
  if ( !mishead ){
    codh = ehh->GetCounter();
    if ( (lastev+1 == firstev && lastev != -1) || (lastev == firstev && lastev != -1) ){      
      if ( IsDebug() ) printf(" B firstev %i lastev %i nevents %i \n",firstev,lastev,lastev-firstev+1);
      firstev = 1;
      lastev = 0;
    } else {
      firstev = codh->Get(pctp->Physics);
    };      
    rhtime = this->GetAbsTime(phh->GetOrbitalTime());
    glrun->Set_GL_RUNH(runh,phh);
    firstObt = glrun->GetRUNHEADER_OBT();
    firstPkt = glrun->GetRUNHEADER_PKT();
  };
  if ( !mistrail ){
    codt = eht->GetCounter();
    if ( (lastev+1 == firstev && lastev != -1) || (lastev == firstev && lastev != -1)){      
      if ( IsDebug() ) printf(" C firstev %i lastev %i nevents %i \n",firstev,lastev,lastev-firstev+1);
      lastev = 0;
      firstev = lastev+1;
    } else {
      lastev = codt->Get(pctp->Physics)-1;
    };
    rttime = this->GetAbsTime(pht->GetOrbitalTime());
    glrun->Set_GL_RUNT(runt,pht);
    lastObt = glrun->GetRUNTRAILER_OBT();
    lastPkt = glrun->GetRUNTRAILER_PKT();
  };
  //
  if ( mishead && mistrail && lastev+1 == firstev ) throw -14; // run with no events, no runtrailer, no runheader... unsupported should never arrive here
  //
  if ( mishead ) {
    glrun->Set_GL_RUNH0();
    //
    if ( (lastev+1 == firstev && lastev != -1) || (lastev == firstev && lastev != -1) ){      
      firstObt = lastObt;
      firstPkt = lastPkt;
      rhtime = rttime;
    } else {
      T->GetEntry(firstev);
      ph = eh->GetPscuHeader();	  	
      firstObt = ph->GetOrbitalTime();
      rhtime = this->GetAbsTime(firstObt);
      firstPkt = ph->GetCounter();	  	 
    };
    //
    glrun->SetRUNHEADER_PKT(firstPkt);
    glrun->SetRUNHEADER_OBT(firstObt);
    //
  };
  if ( mistrail ){
    glrun->Set_GL_RUNT0();
    //
    if ( (lastev+1 == firstev && lastev != -1) || (lastev == firstev && lastev != -1) ){      
      lastObt = firstObt;
      lastPkt = firstPkt;
      rttime = rhtime;
    } else {
      T->GetEntry(lastev);
      ph = eh->GetPscuHeader();	
      lastObt = ph->GetOrbitalTime();
      rttime = this->GetAbsTime(lastObt);
      lastPkt = ph->GetCounter();	  	 
    };
    //
    glrun->SetRUNTRAILER_OBT(lastObt);
    glrun->SetRUNTRAILER_PKT(lastPkt);
    //    
  };
  //
  // ad hoc solution for INF EV_TO [8RED] 090113
  //
  if ( !firstev && lastev == -1 ){
    if ( IsDebug() ) printf(" EE firstev %i lastev %i nevents %i \n",firstev,lastev,lastev-firstev+1);
    firstev = 1;
    lastev = 0;
  };
  glrun->SetEV_FROM((UInt_t)firstev);
  glrun->SetEV_TO((UInt_t)lastev);
  glrun->SetNEVENTS((UInt_t)lastev-(UInt_t)firstev+1);
  //
  if ( IsDebug() ) printf(" firstev %i lastev %i nevents %i \n",firstev,lastev,lastev-firstev+1);
  //
  this->SetCommonGLRUN(rhtime,rttime);
  this->SetPhysEndRunVariables();
  //
};

//
// PUBLIC FUNCTIONS
//

/**
 * Insert a new row into GL_RAW table.
 */
Int_t PamelaDBOperations::insertPamelaRawFile(){

    //
    Bool_t idr =  this->SetID_RAW();
    if ( idr ) return(1);

    GL_RAW glraw = GL_RAW();
    
    glraw.PATH = GetRawPath();
    glraw.NAME = GetRawFile();
    //    glraw.BOOT_NUMBER = 0;//???
    glraw.BOOT_NUMBER = this->GetBOOTnumber();
    
    if( insertPamelaRawFile(&glraw) )return(1);
    //
    idr =  this->SetID_RAW();
    if ( !idr ) throw -11;
    
    return(0);
}
/**
 * Insert a new row into GL_RAW table.
 */
Int_t PamelaDBOperations::insertPamelaRawFile(GL_RAW *glraw){
  //
    if(!glraw)return(1);//?? ok I think
    //
    stringstream oss;
    //
    oss.str("");
    if ( STATIC ){
	oss << "INSERT INTO GL_RAW (PATH, NAME) VALUES ('"
	    << glraw->PATH << "', '" << glraw->NAME << "')";
    } else {
	oss << "INSERT INTO GL_RAW (PATH, NAME) VALUES ('$PAM_RAW', '" << glraw->NAME << "')";
    };
    if ( debug ) cout <<oss.str().c_str() <<endl;
    if ( conn->Query(oss.str().c_str()) == 0 ) throw -4;
    //
    oss.str("");
    oss << "SELECT ID FROM GL_RAW WHERE NAME=\""<<glraw->NAME<<"\";";
    if ( debug ) cout << oss.str().c_str()<<endl;
    if ( conn->Query(oss.str().c_str()) == 0 ) throw -4;
    //
    TSQLResult *result = 0;
    TSQLRow    *row    = 0;
    result = conn->Query(oss.str().c_str());
    if ( result == NULL ) throw -4;
    row = result->Next();
    if ( !row ) return(1);
    glraw->ID = (UInt_t)atoll(row->GetField(0));
    if ( debug ) printf(" The ID of the RAW file is %u \n",glraw->ID);
    delete result;
    delete row;
    //
    return(0);
}


/**
 * Look for one timesync information in the file and
 * fill the GL_TIMESYNC table. It will look for: 1) TS-MCMD 2) TS info in the RunHeader 3) TS info in the runtrailer, if none exists exit with error
 */
Int_t PamelaDBOperations::insertPamelaGL_TIMESYNC(){
  //
  Int_t signal = 0;
  //  UInt_t idresof = 0;
  idresof = 0;
  stringstream   oss;
  TSQLResult *result = 0;
  TSQLRow *row = 0;
  UInt_t OBT = 0;
  UInt_t TYPE = 0;
  UInt_t TSYNC = 0;
  UInt_t t0 = 0;
  Bool_t existsts = false;
  //
  if ( chewbacca ){
    //
    OBT = chobtts * 1000;
    TSYNC = chlastts; 
    t0 = chresursts;
    TYPE = 777;
    oss.str("");
    oss << "select * from GL_RESURS_OFFSET where OFFSET_DATE=FROM_UNIXTIME("<< t0 <<") limit 1;";
    if ( IsDebug() ) printf(" %s \n",oss.str().c_str());
    result = conn->Query(oss.str().c_str());
    if ( !result ) throw -10;
    row = result->Next();
    if ( !row ) throw -92;
    idresof = (UInt_t)atoll(row->GetField(0));
    existsts = true;
    goto eout;
    //  
  } else {
    //
    //signal = this->SetUpperLimits();
    //
    if ( this->GetID_RAW() == 0 )  throw -11;
    //
    oss.str("");
    oss << "SELECT YEAR(OFFSET_DATE),MONTH(OFFSET_DATE),DAY(OFFSET_DATE),HOUR(OFFSET_DATE),MINUTE(OFFSET_DATE),SECOND(OFFSET_DATE),ID FROM GL_RESURS_OFFSET WHERE SPECIAL_FILE='" 
	<< this->GetRawFile().Data() << "';";
    if ( IsDebug() ) printf(" %s \n",oss.str().c_str());
    result = conn->Query(oss.str().c_str());
    if ( !result ) throw -10;
    row = result->Next();
    //
    if ( !row ){
      oss.str("");
      oss << "SELECT YEAR(OFFSET_DATE),MONTH(OFFSET_DATE),DAY(OFFSET_DATE),HOUR(OFFSET_DATE),MINUTE(OFFSET_DATE),SECOND(OFFSET_DATE),ID FROM GL_RESURS_OFFSET WHERE FROM_ORBIT< " 
	  << dworbit << " AND SPECIAL_FILE='' order by FROM_ORBIT desc limit 1;";
      if ( IsDebug() ) printf(" %s \n",oss.str().c_str());
      result = conn->Query(oss.str().c_str());
      if ( !result ) throw -10;
      row = result->Next();
      if ( !row ) throw -10;
    };
    //
    idresof = (UInt_t)atoll(row->GetField(6));
    //
    TTimeStamp tu = TTimeStamp((UInt_t)atoi(row->GetField(0)),(UInt_t)atoi(row->GetField(1)),(UInt_t)atoi(row->GetField(2)),(UInt_t)atoi(row->GetField(3)),(UInt_t)atoi(row->GetField(4)),(UInt_t)atoi(row->GetField(5)),0,true,0);
    t0 = (UInt_t)tu.GetSec();
    if ( IsDebug() ) printf(" t0 is %u ti is %s %s %s %s %s %s %s\n",t0,row->GetField(0),row->GetField(1),row->GetField(2),row->GetField(3),row->GetField(4),row->GetField(5),row->GetField(6));
    //
    /*
     * Verify that the TIMESYNC have been not already processed
     */
    oss.str("");
    oss << " SELECT COUNT(GL_TIMESYNC.ID),GL_TIMESYNC.OBT0,GL_TIMESYNC.TIMESYNC FROM GL_TIMESYNC "
	<< " LEFT JOIN GL_RAW "
	<< " ON GL_RAW.ID = GL_TIMESYNC.ID_RAW "
	<< " WHERE GL_TIMESYNC.ID_RAW = " << this->GetID_RAW() 
	<< " GROUP BY GL_TIMESYNC.OBT0;";
    if ( IsDebug() ) printf(" check for old timesync: query is \n %s \n",oss.str().c_str());
    result = conn->Query(oss.str().c_str());
    if (result == NULL) throw -10;
    row = result->Next();
    if ((row != NULL) && ((UInt_t)atoll(row->GetField(0)) > 0)){
      if ( IsDebug() ) printf(" found a timesync t0 is %u \n",t0);
      toffset = (UInt_t)atoll(row->GetField(2)) - (UInt_t)(this->OBT((UInt_t)atoll(row->GetField(1)))/1000) + t0;
      //
      tsync = (UInt_t)atoll(row->GetField(2));
      obt0 = (UInt_t)atoll(row->GetField(1));
      //
      if ( PEDANTIC ) throw -67;
      return(1);
    };
    //
    TTree *T = 0;
    //
    UInt_t nevent = 0;
    UInt_t recEntries = 0;
    //
    OBT = 0;
    TYPE = 0;
    TSYNC = 0;
    //
    //    Double_t minimum = 0.;
    // Double_t maximum = 0.;
    //Double_t minimum2 = 0.;
    Double_t maximum2 = 0.;
    //
    //
    pamela::McmdEvent *mc = 0;
    pamela::McmdRecord *mcrc = 0;
    TArrayC *mcmddata = 0;
    //
    //    minimum = numeric_limits<Double_t>::max();
    //    maximum = numeric_limits<Double_t>::min();
    //    minimum2 = numeric_limits<Double_t>::max();
    maximum2 = numeric_limits<Double_t>::min();
    //
    T = (TTree*)file->Get("Mcmd");
    if ( !T || T->IsZombie() ) throw -19;
    T->SetBranchAddress("Mcmd",&mc);
    //
    nevent = T->GetEntries();
    //
    // loop over events
    //
    existsts = false;
    //
    for (UInt_t i=0; i<nevent;i++){
      //
      T->GetEntry(i);
      //
      recEntries = mc->Records->GetEntries();
      //
      for (UInt_t j = 0; j < recEntries; j++){
	mcrc = (pamela::McmdRecord*)mc->Records->At(j);
	mcmddata = mcrc->McmdData;
	//
	if (mcrc->ID1 == 0xE0){ // mcmd timesync
	  //
	  OBT = (Int_t)(mcrc->MCMD_RECORD_OBT);
	  //
	  TSYNC = (((UInt_t)mcmddata->At(0)<<24)&0xFF000000) +  (((UInt_t)mcmddata->At(1)<<16)&0x00FF0000) + (((UInt_t)mcmddata->At(2)<<8)&0x0000FF00) + (((UInt_t)mcmddata->At(3))&0x000000FF);
	  //
	  TYPE = 55;//224;
	  //
	  if ( IsDebug() ) printf("mcmd tsync %i tsync %u obt %u \n",i,TSYNC,OBT);
	  //
	  if ( TSYNC && OBT ){
	    existsts = true;
	    goto eout;
	  };
	  //
	};
      };
    };
    if ( !existsts ) { // try with runheader and runtrailer
      //
      if ( IsDebug() ) printf(" No ts mcmd \n");
      signal = 2;
      //
      TTree *rh=(TTree*)file->Get("RunHeader");
      if ( !rh || rh->IsZombie() ) throw -17;
      TTree *rt=(TTree*)file->Get("RunTrailer");
      if ( !rt || rt->IsZombie() ) throw -18;
      //
      rh->SetBranchAddress("RunHeader", &runh);
      //
      rt->SetBranchAddress("RunTrailer", &runt);
      //
      Int_t nnrhev = rh->GetEntries();
      Int_t nnrtev = rt->GetEntries();
      if ( IsDebug() ) printf(" ou nevent %i rhev %i rtev %i \n",nevent,nnrhev,nnrtev);
      //
      if ( nnrhev > 0 ){
	for (Int_t i=0; i<nnrhev; i++){
	  //
	  rh->GetEntry(i);
	  //
	  TSYNC = runh->LAST_TIME_SYNC_INFO;
	  OBT = runh->OBT_TIME_SYNC * 1000;
	  //
	  TYPE = 20;
	  //
	  if ( IsDebug() ) printf("runheader %i tsync %u obt %u \n",i,TSYNC,OBT);
	  //
	  if ( TSYNC && OBT ){
	    existsts = true;
	    goto eout;
	  };
	};
	//
      };
      if ( nnrtev > 0 ){
	//
	if ( IsDebug() ) printf(" No runheader \n");
	signal = 6;
	//
	for (Int_t i=0; i<nnrtev; i++){
	  //
	  rt->GetEntry(i);
	  //
	  TSYNC = runt->LAST_TYME_SYNC_INFO;
	  OBT = runt->OBT_TYME_SYNC * 1000;
	  //
	  TYPE = 21;
	  //
	  if ( IsDebug() ) printf("runtrailer %i tsync %u obt %u \n",i,TSYNC,OBT);
	  //
	  if ( TSYNC && OBT ){
	    existsts = true;
	    goto eout;
	  };
	};
	//
      } else {
	if ( IsDebug() ) printf(" No runheader \n");
      };
    };
    //
    if ( !existsts ){ // try with inclination mcmd
      //
      if ( IsDebug() ) printf(" No runtrailer \n");
      signal = 14;
      //
      Double_t timesync = 0.;
      for (UInt_t i=0; i<nevent;i++){
	//
	T->GetEntry(i);
	//
	recEntries = mc->Records->GetEntries();
	//      //
	for (UInt_t j = 0; j < recEntries; j++){
	  mcrc = (pamela::McmdRecord*)mc->Records->At(j);
	  mcmddata = mcrc->McmdData;
	  //
	  if (mcrc->ID1 == 0xE2){ // mcmd inclination  
	    timesync = 0.;
	    timesync = (Double_t)(((((UInt_t)mcmddata->At(0) << 24) & 0xFF000000) + (((UInt_t)mcmddata->At(1) << 16) & 0x00FF0000) + (((UInt_t)mcmddata->At(2) << 8) & 0x0000FF00) + ((UInt_t)mcmddata->At(3) & 0x000000FF))/128.0);
	    //
	    if ( timesync > maximum2){
	      maximum2 = timesync;
	      OBT = (Int_t)(mcrc->MCMD_RECORD_OBT);
	    };
	  };
	  //
	};
      };
      if ( maximum2 > numeric_limits<Double_t>::min() ){
	TSYNC = (UInt_t)(maximum2 + 0.5); 
	TYPE = 666;
	if ( TSYNC && OBT ){
	  existsts = true;
	  goto eout;
	};
      };
    };
    //
  };
  //
  if ( !existsts && obt0 ){ // insert timesync by hand
    //
    if ( PEDANTIC ) throw -68;
    if ( IsDebug() ) printf(" No incl mcmd \n");
    signal = 30;
    //
    OBT = obt0;
    TSYNC = tsync; 
    TYPE = 999;
    existsts = true;
    goto eout;
  };
  //
 eout:
  //
  if ( !existsts ) throw -3;
  //
  oss.str("");
  oss << "INSERT INTO GL_TIMESYNC (ID_RAW,TYPE,OBT0,TIMESYNC,ID_RESURS_OFFSET) VALUES ('"
      << this->GetID_RAW() << "','"//224'"
      << dec << (UInt_t)TYPE << "','"
      << dec << (UInt_t)OBT << "','"
      << dec << (UInt_t)TSYNC << "','"
      << dec << (UInt_t)idresof << "');";
  conn->Query(oss.str().c_str());
  if ( IsDebug() ) printf(" Query the GL_TIMESYNC table to fill it:\n %s \n",oss.str().c_str()); 
  if ( conn->GetErrorCode() ){
    printf(" OK, you got an error because the database structure you are using is not up to date\n Using backward compability code, hence you can continue safetly \n");
    oss.str("");
    oss << "INSERT INTO GL_TIMESYNC (ID_RAW,TYPE,OBT0,TIMESYNC) VALUES ('"
	<< this->GetID_RAW() << "','"//224'"
	<< dec << (UInt_t)TYPE << "','"
	<< dec << (UInt_t)OBT << "','"
	<< dec << (UInt_t)TSYNC << "');";
    conn->Query(oss.str().c_str());
    if ( IsDebug() ) printf(" Query the GL_TIMESYNC table to fill it:\n %s \n",oss.str().c_str()); 
  };
  //
  if ( IsDebug() ) printf(" found a timesync t0 is %u \n",t0);
  //
  toffset = (UInt_t)TSYNC - (UInt_t)(this->OBT(OBT)/1000) + t0;
  //
  tsync = TSYNC;
  obt0 = OBT;
  //
  delete result;
  return(signal);
}

/**
 * Insert all the new rows into GL_ROOT. 
 * The raw file indicates in the parameters should be already been stored in the database.
 */
Int_t PamelaDBOperations::insertPamelaRootFile(){

    stringstream oss;
    TSQLResult *result = 0;
    TSQLRow    *row    = 0;
    //
    // ----------------------
    // determine the timesync
    // ----------------------
    UInt_t idtimesync = 0;
    //
    if ( chewbacca ){
	oss.str("");
	oss << " SELECT ID FROM GL_TIMESYNC where TIMESYNC="<<chlastts<<" AND OBT0="<<chobtts*1000<<" and ID_RESURS_OFFSET="<< idresof <<" limit 1;"; // 10RED BUG!!!! without 'and ID_RESURS_OFFSET="<< idresof ' this query is not enough to ensure finding the correct line in GL_TIMSYNC...
	if ( debug ) printf(" %s \n",oss.str().c_str());
	result = conn->Query(oss.str().c_str());
	//
	if ( !result ) throw -3;
	//
	row = result->Next();
	//
	if ( !row ) throw -3;
	idtimesync = (UInt_t)atoll(row->GetField(0));
    } else {
	oss.str("");
	if ( STATIC ){
	    oss << " SELECT COUNT(GL_ROOT.ID_RAW),GL_RAW.ID,GL_ROOT.ID FROM GL_RAW "
		<< " LEFT JOIN GL_ROOT "
		<< " ON GL_RAW.ID = GL_ROOT.ID_RAW "
		<< " WHERE GL_RAW.PATH = '" << this->GetRawPath().Data() << "' AND "
		<< " GL_RAW.NAME = '" << this->GetRawFile().Data() << "' GROUP BY GL_RAW.ID ";
	} else {
	    oss << " SELECT COUNT(GL_ROOT.ID_RAW),GL_RAW.ID,GL_ROOT.ID FROM GL_RAW "
		<< " LEFT JOIN GL_ROOT "
		<< " ON GL_RAW.ID = GL_ROOT.ID_RAW "
		<< " WHERE GL_RAW.PATH = '$PAM_RAW' AND "
		<< " GL_RAW.NAME = '" << this->GetRawFile().Data() << "' GROUP BY GL_RAW.ID ";
	};
	result = conn->Query(oss.str().c_str());
	//
	if ( !result ) throw -12;
	//
	row = result->Next();
	//
	if ( !row ) throw -10;
	if ( row != NULL && (UInt_t)atoll(row->GetField(0))>0 ){
	    idroot = (UInt_t)atoll(row->GetField(2));
	    delete row;
	    delete result;
	    return(1);
	};
	//
	// determine which timesync has to be used
	//
	oss.str("");
	oss << "SELECT GL_TIMESYNC.ID FROM GL_TIMESYNC LEFT JOIN GL_RAW ON GL_RAW.ID = GL_TIMESYNC.ID_RAW ORDER BY GL_TIMESYNC.ID DESC LIMIT 1;";
	result = conn->Query(oss.str().c_str());
	//
	if ( !result ) throw -3;
	//
	row = result->Next();
	//
	if ( !row ) throw -3;
	idtimesync = (UInt_t)atoll(row->GetField(0));
    };
    
    delete row;
    delete result;

    // ----------------------
    // insert root file
    // ----------------------

    GL_ROOT glroot = GL_ROOT();
    
    glroot.ID_RAW = GetID_RAW();
    glroot.ID_TIMESYNC = idtimesync;
    if ( STATIC ){
      glroot.PATH = GetRootPath(); 
    } else {
      if ( KEEPENV ){
	glroot.PATH = gSystem->DirName(filerootname.Data());
      } else {
	glroot.PATH = "$PAM_L0";
      };
    };
    glroot.NAME = GetRootFile();

    if ( insertPamelaRootFile(&glroot) )return 1;

    SetID_ROOT(glroot.ID);
    

    return (0);
}
/**
 * Insert all the new rows into GL_ROOT. 
 * The raw file indicates in the parameters should be already been stored in the database.
 */
Int_t PamelaDBOperations::insertPamelaRootFile(GL_ROOT *glroot){
  stringstream oss;
  TSQLResult *result = 0;
  TSQLRow    *row    = 0;
  //
  //
  oss.str("");
  oss << "INSERT INTO GL_ROOT (ID_RAW, ID_TIMESYNC,PATH, NAME) VALUES ('"
      << glroot->ID_RAW << "', '" << glroot->ID_TIMESYNC << "', '" << glroot->PATH << "', '" << glroot->NAME << "')";
  //
  if ( debug ) printf("%s \n",oss.str().c_str());
  if (conn->Query(oss.str().c_str()) == 0) throw -4;
  //
  delete result;
  //
  oss.str("");
  //  oss << "SELECT ID FROM GL_ROOT WHERE ID_RAW=" << this->GetID_RAW() << ";";
  oss << "SELECT ID FROM GL_ROOT WHERE PATH='" << glroot->PATH << "' and NAME='"<< glroot->NAME <<"';";
  //
  if ( debug ) printf("%s \n",oss.str().c_str());
  result = conn->Query(oss.str().c_str());
  if ( !result ) throw -12;
  row = result->Next();
  if ( !row ) throw -3;

  glroot->ID = (UInt_t)atoll(row->GetField(0));

  if ( debug ) printf(" The ID of the ROOT file is %u \n",glroot->ID);
  //
  delete result;
  //
  return(0);
}

/**
 * Assign the BOOT_NUMBER to the raw file.
 */
Int_t PamelaDBOperations::assignBOOT_NUMBER(){
  Bool_t found = false;
  UInt_t idRaw = 0;
  UInt_t bn = 0;
  stringstream oss;
  TSQLResult *result = 0;
  TSQLRow    *row    = 0;
  if ( chewbacca ){
    if ( chboot == 1 ){
      // not found!
      found = false;
    } else {
      found = true;
      this->SetBOOTnumber(chboot);
    };
  } else {
    oss.str("");
    if ( STATIC ){
      oss << "SELECT ID, BOOT_NUMBER FROM GL_RAW WHERE "
	  << " PATH = '" << this->GetRawPath().Data() << "' AND "
	  << " NAME = '" << this->GetRawFile().Data() << "' ";
    } else {
      oss << "SELECT ID, BOOT_NUMBER FROM GL_RAW WHERE "
	  << " PATH = '$PAM_RAW' AND "
	  << " NAME = '" << this->GetRawFile().Data() << "' ";
    };
    result = conn->Query(oss.str().c_str());
    //
    if ( !result ) throw -4;;
    row = result->Next();
    if ( !row ) return(16);
    if ( row->GetField(1) ){
      this->SetBOOTnumber((UInt_t)atoll(row->GetField(1)));
      return(1);
    };
    if ( !row->GetField(0) ) throw -26;
    //
    idRaw = (UInt_t)atoll(row->GetField(0));
    //
    //
    //
    TTree *trDumpEv = 0;
    trDumpEv = (TTree*)file->Get("VarDump");
    if ( !trDumpEv || trDumpEv->IsZombie() ) throw -20;
    //
    VarDumpEvent  *vde = 0;
    VarDumpRecord *vdr = 0;
    //
    trDumpEv->SetBranchAddress("VarDump", &vde);
    if ( trDumpEv->GetEntries() > 0 ){
      found = false;
      for ( Int_t i = 0; i < trDumpEv->GetEntries(); i++){
	trDumpEv->GetEntry(i);
	//      vde->Records->GetEntries();
	if ( vde->Records->GetEntries()>5 ){
	  found = true;
	  goto fill;
	};
      };
    fill:
      if ( found ){
	//
	vdr = (VarDumpRecord*)vde->Records->At(6);
	//
	this->SetBOOTnumber((Int_t)vdr->VAR_VALUE);
	//
      } else {
	if ( !this->GetBOOTnumber() && !this->AutoBoot()) return(4);
      };
    } else {
      if ( !this->GetBOOTnumber() && !this->AutoBoot()) return(2);
    };  
    //
  };
  //
  Bool_t afound = false;
  if ( !found && this->AutoBoot()){
    afound = true;
    //
    // Search for other files with similar timesync
    //
    if ( IsDebug() ) printf(" tsync %u obt0 %u \n",tsync,obt0);
    UInt_t upperts = tsync-(obt0/1000)+5;
    UInt_t lowerts = tsync-(obt0/1000)-5;
    if ( chewbacca ){
      oss.str("");
      oss << "select BOOT_NUMBER from ROOT_TABLE where CAST((LAST_TIME_SYNC_INFO-(OBT_TIME_SYNC)) AS SIGNED INT)<" // 10RED MYSQL OPERATORS BUG
	  << upperts 
	  << " AND CAST((LAST_TIME_SYNC_INFO-(OBT_TIME_SYNC)) AS SIGNED INT)>" // 10RED MYSQL OPERATORS BUG
	  << lowerts
	  << " AND BOOT_NUMBER>1;";
    } else {
      oss.str("");
      oss << "select GL_RAW.BOOT_NUMBER from GL_TIMESYNC LEFT JOIN GL_RAW ON GL_RAW.ID = GL_TIMESYNC.ID_RAW where CAST((TIMESYNC-(OBT0/1000)) AS SIGNED INT)<" // 10RED MYSQL OPERATORS BUG
	  << upperts 
	  << " AND CAST((TIMESYNC-(OBT0/1000)) AS SIGNED INT)>" // 10RED MYSQL OPERATORS BUG
	  << lowerts
	  << " AND GL_RAW.BOOT_NUMBER>0 GROUP BY GL_TIMESYNC.OBT0;";
    };
    result = conn->Query(oss.str().c_str());
    if ( IsDebug() && !chewbacca ) printf(" Query the GL_TIMESYNC table to find boot number:\n %s \n",oss.str().c_str()); 
    if ( IsDebug() && chewbacca ) printf(" Query the ROOT_TABLE table to find boot number:\n %s \n",oss.str().c_str()); 
    //
    if ( !result ) throw -4;;
    found = true;
    if ( result->GetRowCount()<3 ){
      if ( IsDebug() ) printf(" AGH! no results!\n");
      found = false;
    } else {
      row = result->Next();      
      bn = (UInt_t)atoll(row->GetField(0)); 
      for ( Int_t r=1; r<result->GetRowCount() ;r++){
	if ( !row ) throw -4;
	if ( IsDebug() ) printf(" BOOT number is %s \n",row->GetField(0));
	if ( bn != (UInt_t)atoll(row->GetField(0)) ){
	  if ( IsDebug() ) printf(" AGH! bn = %u here instead %u \n",bn,(UInt_t)atoll(row->GetField(0)));
	  found = false;
	};
	row = result->Next();
      };
    };
  };
  //
  Int_t sgn = 0;
  //
  if ( !found && !BOOTNO ){
    throw -29;
  } else {
    if ( afound ){
      this->SetBOOTnumber(bn);
      sgn = 8;
    };
  };
  //
  if ( !chewbacca ){
    oss.str("");
    oss << " UPDATE GL_RAW "
	<< " SET GL_RAW.BOOT_NUMBER = '" << dec << this->GetBOOTnumber() << "'"
	<< " WHERE GL_RAW.ID = '" << idRaw << "'";
    conn->Query(oss.str().c_str());	
  };
  //
  delete result;
  return(sgn);
};

/**
 * Scan runtrailer packet, fill the GL_RUN table and
 * check for missing and truncated runs
 */
Int_t PamelaDBOperations::insertPamelaRUN(){
  Int_t signal = 0;
  //
  stringstream oss;
  oss.str("");
  //
  //  signal = this->SetUpperLimits();

  //
  // loop on runheader and runtrailer events
  //
  TTree *rh=(TTree*)file->Get("RunHeader");
  if ( !rh || rh->IsZombie() ) throw -17;
  TTree *rt=(TTree*)file->Get("RunTrailer");
  if ( !rt || rt->IsZombie() ) throw -18;
  //
  PacketType *pctp=0;
  EventCounter *cod=0;
  //
  rh->SetBranchAddress("RunHeader", &runh);
  rh->SetBranchAddress("Header", &ehh);
  //
  rt->SetBranchAddress("RunTrailer", &runt);
  rt->SetBranchAddress("Header", &eht);
  //
  TTree *T = (TTree*)file->Get("Physics");
  if ( !T || T->IsZombie() ) throw -16;
  EventHeader *eh = 0;
  T->SetBranchAddress("Header", &eh);
  //
  if ( !(rh->GetEntries()) && !(rt->GetEntries()) && !(T->GetEntries()) ) return(16);
  //
  UInt_t obtt = 0;
  UInt_t obth = 0;
  UInt_t pktt = 0;
  UInt_t pkth = 0;
  Int_t pth = -1;
  Int_t ptht = -1;
  Int_t evbeft = 0;
  Int_t evbefh = 0;
  UInt_t tcod;
  //
  // no runtrailers in the file!
  //
  if ( IsDebug() ) printf(" Start rtev %i rhev %i nrtev %i nrhev %i \n",rtev,rhev,nrtev,nrhev); 
  if ( !rtev || (chewbacca && !nrtev) ){
    if ( IsDebug() ) printf(" No runtrailers \n"); 
    if ( !rhev || (chewbacca && !nrhev) ){
      if ( IsDebug() ) printf(" No runheaders nor runtrailers!! \n"); 
      if ( !(upperentry-chminentry) ){
	if ( IsDebug() ) printf(" No physics events nor runs in the file \n"); // di nuovo potrebbe esserci un runtrailer senza eventi (riempimento MM)
	//      throw -8;
	return 0; // one could check if there is any calibration no need to exit with error
      } else {
	this->HandleRunFragments(true,true,chminentry,upperentry);  // no runtrailers ma potrebbe esserci un runheader ora...
      };
    } else {
      //
      // we have runheaders but not runtrailers!
      //
      if ( debug ) printf(" We have runheaders (%i) but not runtrailers (%i) ! \n",rhev,rtev);
      for ( pth=0; pth < rhev; pth++ ){
	rh->GetEntry(pth);
	phh = ehh->GetPscuHeader();
	pkth = phh->GetCounter();
	obth = phh->GetOrbitalTime();
	if ( PKT(pkth) >= PKT(pktfirst) && PKT(pkth) <= upperpkt ){
	  cod = ehh->GetCounter();
	  tcod = (UInt_t)cod->Get(pctp->Physics);
	  evbefh = TMath::Max(chminentry,tcod);
	  //	  if ( (UInt_t)evbefh == upperentry ) evbefh = upperentry + 1;  // this does not work due to the Counter bug in chewbacca
	  if ( (UInt_t)evbefh == upperentry || !upperentry ) evbefh = upperentry + 1;
	  //
	  if ( debug ) printf(" evbefh %i upperentry %u \n",evbefh,upperentry);
	  //
	  this->HandleRunFragments(false,true,evbefh,upperentry); 
	  //
	};
      };
      //
    };
    //
  } else {
    //
    if ( IsDebug() ) printf(" We have runtrailers \n"); 
    Int_t conptt = -1;
    for (Int_t ptt=0; ptt<rtev; ptt++){
      //
      rt->GetEntry(ptt);
      pht = eht->GetPscuHeader();
      pktt = pht->GetCounter();
      obtt = pht->GetOrbitalTime();
      //
      if ( PKT(pktt) >= PKT(pktfirst) && PKT(pktt) <= upperpkt ){
	//
	conptt++;
	//
	cod = eht->GetCounter();
	ptht = cod->Get(pctp->RunHeader) - 1;
	//      evbeft = cod->Get(pctp->Physics);
	tcod = (UInt_t)cod->Get(pctp->Physics);
	if ( !tcod ) tcod = 1;    // IS A BUG SINCE RUNS WITH ZERO EVENTS WILL LOOK LIKE RUNS WITH ONE EVENT
	evbeft = TMath::Min(upperentry,(tcod-1));
	if ( debug ) printf(" Loop in runtrailers, evbeft is %u upperentry %u cod->getetc %u \n",evbeft,upperentry,cod->Get(pctp->Physics));
	//
	//	if ( !conptt &&  !(ptht+1) ){ // here we assume ptht+1 = 0 at the beginning of the interval that could not be true if the interval start from middle file... it must be equal to the number of RH before the interval that is not counted anywhere 
	if ( !conptt &&  (ptht+1) == nrhbef ){ 
	  //
	  if ( IsDebug() ) printf(" Piece of run at the beginning of the file %i %i %u \n",ptht,pth,ptt); 
	  //
	  this->HandleRunFragments(true,false,chminentry,(evbeft)); 
	  //
	  pth = ptht;  // ??
	  //
	} else if ( pth == ptht ){
	  //
	  if ( IsDebug() ) printf(" Missing header %i %i %u\n",ptht,pth,ptt); 
	  //
	  if ( (ptt-1) < 0 ) throw -15; // should never arrive here!
	  rt->GetEntry(ptt-1);
	  cod = eht->GetCounter();
	  tcod = (UInt_t)cod->Get(pctp->Physics);
	  evbefh = TMath::Max(chminentry,tcod);
	  //evbefh = cod->Get(pctp->Physics);
	  rt->GetEntry(ptt);
	  pht = eht->GetPscuHeader();
	  //
	  if ( IsDebug() ) printf(" Try to find the beginning of a run which has only the runtrailer   %i %i %u \n",ptht,pth,ptt); 
	  if ( IsDebug() ) printf(" '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  %u %u %u \n",pkth,obth,obtt);
	  //
	  this->HandleMissingHoT(true,false,evbefh,(evbeft)); 
	  //
	} else {
	  //
	  rh->GetEntry(ptht);
	  phh = ehh->GetPscuHeader();
	  pkth = phh->GetCounter();
	  obth = phh->GetOrbitalTime();
	  cod = ehh->GetCounter();
	  tcod = (UInt_t)cod->Get(pctp->Physics);
	  if ( !tcod ) tcod = 1; // IS A BUG SINCE RUNS WITH ZERO EVENTS WILL LOOK LIKE RUNS WITH ONE EVENT
	  evbefh = TMath::Max(chminentry,(tcod-1));
	  // 
	  if ( PKT(pkth) >= PKT(pktfirst) && PKT(pkth) <= upperpkt ){
	    if ( IsDebug() ) printf(" Could be a good run, we have a runheader followed by a runtrailer %i %i %u\n",ptht,pth,ptt); 
	    //
	    //	evbefh = cod->Get(pctp->Physics);
	    if ( IsDebug() ) printf(" ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' %u %u %u \n",pkth,obth,obtt);
	    //
	    // handle this run
	    //
	    this->HandleRun();
	    //
	    //
	    if ( debug ) printf(" Standard case, evbefh is %u chminentry %u cod->getetc %u \n",evbefh,chminentry,cod->Get(pctp->Physics));
	    //
	  } else {
	    // missing header in the considered interval!
	    if ( debug ) printf(" Missing header in the considered interval \n");
	    this->HandleRunFragments(true,false,evbefh,evbeft); 
	  };
	  //
	  if ( PKT(pkth)>PKT(pktfirst) && OBT(obth)>OBT(obtfirst) && PKT(pkth)<=(upperpkt)  && !conptt ){
	    //
	    if ( IsDebug() ) printf(" Piece of run at the beginning of the file WITH NO RUNTRAILER evbefh = %u \n",evbefh); 	  
	    //
	    if ( evbefh == 0 ) { 
	      //
	      if ( !chewbacca ){
		signal = 8;
		if ( IsDebug() ) printf(" Not supported yet: run with no events, no runtrailer, no runheader \n");
	      } else {
		if ( debug ) printf(" The file does not start with a physics packet, no problem continue \n");
	      };
	      //
	    } else {
	      //
	      this->HandleRunFragments(true,true,chminentry,(evbefh)); 
	      //
	      // what about pth=ptht-1
	    };
	  };
	  //
	  //
	  if ( (ptht - pth) > 1 ){
	    //
	    if ( IsDebug() ) printf(" Missing runtrailers! \n"); 
	    if ( IsDebug() ) printf(" Attention there is a jump in the runheader counter %i %i %u \n",ptht,pth,ptt); 
	    // is not the consecutive header
	    while ( pth != ptht ){	  
	      //
	      // treat the header(s) in the middle and then go to the next header, repeat until you reach the correct header.
	      //
	      pth++;
	      //
	      rh->GetEntry(pth+1);
	      phh = ehh->GetPscuHeader();
	      pktt = phh->GetCounter();
	      obtt = phh->GetOrbitalTime();
	      cod = ehh->GetCounter();
	      //	    evbeft = cod->Get(pctp->Physics);
	      tcod = (UInt_t)cod->Get(pctp->Physics);
	      if ( !tcod ) tcod = 1; // IS A BUG SINCE RUNS WITH ZERO EVENTS WILL LOOK LIKE RUNS WITH ONE EVENT
	      evbeft = TMath::Min(upperentry,(tcod-1));
	      rh->GetEntry(pth);
	      phh = ehh->GetPscuHeader();
	      cod = ehh->GetCounter();
	      pkth = phh->GetCounter();
	      obth = phh->GetOrbitalTime();
	      //evbefh = cod->Get(pctp->Physics);
	      tcod = (UInt_t)cod->Get(pctp->Physics);
	      evbefh = TMath::Max(chminentry,tcod);
	      //
	      if ( PKT(pkth) >= PKT(pktfirst) && PKT(pkth) <= upperpkt && pth != ptht ){
		//
		if ( IsDebug() ) printf(" Try to find the end of a run which has only the runheader   %i %i %u \n",ptht,pth,ptt); 
		if ( IsDebug() ) printf(" ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' %u %u %u \n",pkth,obth,obtt);
		//
		this->HandleMissingHoT(false,true,evbefh,evbeft); 
		//
	      };
	    };
	    //
	  } else if ( !(ptht - pth) ){
	    //
	    if ( IsDebug() ) printf(" Missing runheader! \n"); 
	    if ( IsDebug() ) printf(" Attention! the runheader counter did not changed %i %i %u \n",ptht,pth,ptt); 
	    if ( IsDebug() ) printf(" The run should have already been handled by HandleRun() \n"); 
	    if ( PEDANTIC ) throw -87;
	    //
	  } else {
	    //
	    // go on with next header
	    //
	    pth = ptht;
	  };
	  //           
	};
	//
	//	if ( ptt+1 == rtev){  
	if ( conptt+1 == nrtev ){  
	  //	if ( conptt+1 == (nrtev+nrtbef )){  
	  if ( IsDebug() ) printf(" >>>>>>>>>>> %i %u %i %u \n",ptht,rhev,nrtev,conptt); 
	  ptht++;
	  if ( ptht < rhev ){ 
	    rh->GetEntry(ptht);
	    //pth++;
	    //if ( pth < rhev ){
	    //rh->GetEntry(pth);
	    phh = ehh->GetPscuHeader();
	    pkth = phh->GetCounter();
	    obth = phh->GetOrbitalTime();
	    cod = ehh->GetCounter();
	    tcod = (UInt_t)cod->Get(pctp->Physics);
	    evbefh = TMath::Max(chminentry,tcod);
	    if ( PKT(pkth) >= PKT(pktfirst) && PKT(pkth) <= upperpkt ){
	      //	    evbefh = cod->Get(pctp->Physics);
	      if ( IsDebug() ) printf(" Piece of run at the end of file %u %u %u \n",pkth,obth,obtt);
	      if ( IsDebug() ) printf(" ''''''''''''''''''''''''''''''' %i %i %u \n",ptht,pth,ptt); 
	      if ( IsDebug() ) printf(" ''''''''''''''''''''''''''''''' %u \n",rhev); 
	      if ( IsDebug() ) printf(" evbefh %u upperentry %u \n",(UInt_t)evbefh,upperentry);
	      //
	      this->HandleRunFragments(false,true,evbefh,upperentry); 
	      //
	    };
	  } else {
	    //
	    // check if we have a fragment with no header
	    //
	    if ( (UInt_t)evbeft < upperentry-1 && upperentry>0 ){
	      if ( IsDebug() ) printf(" Piece of run at the end of the file with NO RUNHEADER! evbeft %u upperentry-1 %u \n",(UInt_t)evbeft,upperentry-1);
	      //
	      //	      if ( (ptt-1) < 0 ) throw -15; // should never arrive here!
	      if ( (rtev-1) < 0 || ptt < 0 ) throw -15; // should never arrive here!
	      //	      rt->GetEntry(ptt-1);
	      rt->GetEntry(rtev-1);
	      cod = eht->GetCounter();
	      tcod = (UInt_t)cod->Get(pctp->Physics)+1;
	      evbefh = TMath::Max(chminentry,tcod);
	      //	    evbefh = cod->Get(pctp->Physics);
	      rt->GetEntry(ptt);
	      pht = eht->GetPscuHeader();	  
	      this->HandleRunFragments(true,true,evbefh,upperentry);
	    };
	  };
	};
	//
      };
    };
  };
  // 
  return(signal);
};

/**
 * 
 *  Check if the run has already been inserted
 * 
 */
Bool_t PamelaDBOperations::IsRunAlreadyInserted(){
  //
  TSQLResult *result = 0;
  TSQLRow    *row    = 0;
  //
  stringstream oss;
  oss.str("");
  //
  // the where clause is of the type: boot_number = _our_boot && (
  //                                  ( runhead_time >= (_our_runhead_time-10) &&  runtrail_time <= (_our_runtrail_time+10) &&
  //                                    ( runhead_obt >= _our_runheadobt || runhead_pkt >= _our_runheadpkt ) && 
  //                                    ( runtrail_obt >= _our_runtrailobt || runtrail_pkt >= _our_runtrailpkt ) ) 
  //                                  || 
  //                                  ( runhead_time <= _our_runhead_time &&  runtrail_time >= _our_runtrail_time && 
  //                                    ( runhead_obt <= _our_runheadobt || runhead_pkt <= _our_runheadpkt ) && 
  //                                    ( runtrail_obt <= _our_runtrailobt || runtrail_pkt <= _our_runtrailpkt ) ) 
  //                                  || 
  //                                  ( runhead_time = _our_runhead_time &&  runtrail_time = _our_runtrail_time && nevents > 100 ) 
  //                                  )
  //                                  || 
  //                                  ( runhead_time = _our_runhead_time &&  runtrail_time > _our_runtrail_time && nevents > 100 ) 
  //                                  )
  //                                  || 
  //                                  ( runhead_time < _our_runhead_time &&  runtrail_time = _our_runtrail_time && nevents > 100 ) 
  //                                  )
  //
  oss << " SELECT ID,NEVENTS,TRK_CALIB_USED,PKT_COUNTER FROM GL_RUN WHERE "
      << " BOOT_NUMBER=" << this->GetBOOTnumber() << " AND ("
      << " (RUNHEADER_TIME>=" << (UInt_t)(glrun->GetRUNHEADER_TIME()-10) << " AND "
      << " RUNTRAILER_TIME<=" << (UInt_t)(glrun->GetRUNTRAILER_TIME()+10) << " AND ("
      << " RUNHEADER_OBT>=" << glrun->GetRUNHEADER_OBT() << " OR "
      << " RUNHEADER_PKT>=" << glrun->GetRUNHEADER_PKT() << ") AND ("
      << " RUNTRAILER_OBT<=" << glrun->GetRUNTRAILER_OBT() << " OR "
      << " RUNTRAILER_PKT<=" << glrun->GetRUNTRAILER_PKT() << ") ) OR "
      << " (RUNHEADER_TIME<=" << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "
      << " RUNTRAILER_TIME>=" << (UInt_t)glrun->GetRUNTRAILER_TIME() <<" AND ("
      << " RUNHEADER_OBT<=" << glrun->GetRUNHEADER_OBT() << " OR "
      << " RUNHEADER_PKT<=" << glrun->GetRUNHEADER_PKT() << ") AND ("
      << " RUNTRAILER_OBT>=" << glrun->GetRUNTRAILER_OBT() << " OR ";
  if ( glrun->GetNEVENTS() < 100 ){ 
    oss<<" RUNTRAILER_PKT>=" << glrun->GetRUNTRAILER_PKT() << "))); ";
  } else {
    oss << " RUNTRAILER_PKT>=" << glrun->GetRUNTRAILER_PKT() << ")) OR "
	<< " (RUNHEADER_TIME=" << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "                //  these two lines in a certain way disable the patch below...
	<< " RUNTRAILER_TIME=" << (UInt_t)glrun->GetRUNTRAILER_TIME() <<" AND NEVENTS>100) OR"    // 
	<< " (RUNHEADER_TIME=" << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "                // 
	<< " RUNTRAILER_TIME>" << (UInt_t)glrun->GetRUNTRAILER_TIME() <<" AND NEVENTS>100) OR"    // 
	<< " (RUNHEADER_TIME<" << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "                // 
	<< " RUNTRAILER_TIME=" << (UInt_t)glrun->GetRUNTRAILER_TIME() <<" AND NEVENTS>100)"    // 
	<< " );";
  };
  //
  if ( IsDebug() ) printf(" THIS RUN: RUNHEADER_OBT %u RUNTRAILER_OBT %u RUNHEADER_PKT %u RUNTRAILER_PKT %u NEVENTS %u\n", glrun->GetRUNHEADER_OBT(),glrun->GetRUNTRAILER_OBT(),glrun->GetRUNHEADER_PKT(),glrun->GetRUNTRAILER_PKT(),glrun->GetNEVENTS());
  if ( IsDebug() ) printf(" check if run has been inserted: query is \n %s \n",oss.str().c_str());
  result = conn->Query(oss.str().c_str());
  //
  if ( !result ) throw -4;
  //
  row = result->Next();
  //
  if ( !row ){
    if ( IsDebug() ) printf(" The run is new \n");
    if ( IsDebug() ) printf(" -> fill the DB \n");
    return(false); // the file has not been inserted in the DB, go on.
  };
  //
  Bool_t signal = true;
  //
  while ( row != NULL ){    
    if ( IsDebug() ) printf(" A run exists with runheader and runtrailer time and packets compatible with this one \n");
    //
    // the run has already been inserted 
    //
    if ( signal && IsDebug() ) printf(" The run has already been inserted\n");    
    if ( PEDANTIC ) throw -86;
    return(true);  //<<<<<<<<<<<<<<<<<<<<<<<< patch follows, uncomment here
    //
    // PATCH!
    // we keep the processing run if (in order of growing importance) 1) we have the runtrailer while the old run doesn't have it 2) we have the runheader 
    // while the old run doesn't have it 3) we have more events than the old run 
    //
    if ( glrun->GetNEVENTS() > (UInt_t)atoll(row->GetField(1)) ){
      //
      if ( IsDebug() ) printf(" The new run has more events than the old one \n");
      glrun->DeleteRun(conn,(UInt_t)atoll(row->GetField(0)),"GL_RUN");
      //       oss.str("");
      //       oss << "DELETE FROM GL_RUN WHERE ID=" << row->GetField(0) <<";";
      //       if ( IsDebug() ) printf(" delete the run entry: query is \n %s \n",oss.str().c_str());      
      //       conn->Query(oss.str().c_str());
      if ( signal ) signal = false;
      goto gonext;      
      //
    } else if ( glrun->GetNEVENTS() < (UInt_t)atoll(row->GetField(1)) ){
      if ( IsDebug() ) printf(" The new run has less events than the old one \n");
      if ( IsDebug() ) printf(" The run is already inserted \n"); 
      goto gonext;
    };
    //
    if ( glrun->GetTRK_CALIB() && !(UInt_t)atoll(row->GetField(2)) ){
      //
      if ( IsDebug() ) printf(" The new run has the same number of events and the runheader the old one miss the runheader \n");
      //
      glrun->DeleteRun(conn,(UInt_t)atoll(row->GetField(0)),"GL_RUN");
      //       oss.str("");
      //       oss << "DELETE FROM GL_RUN WHERE ID=" << row->GetField(0) <<";";
      //       if ( IsDebug() ) printf(" delete the run entry: query is \n %s \n",oss.str().c_str());      
      //       conn->Query(oss.str().c_str());
      //
      if ( signal ) signal = false;
      goto gonext;
    } else if ( !glrun->GetTRK_CALIB() && (UInt_t)atoll(row->GetField(2)) ){
      if ( IsDebug() ) printf(" The new run has the same number of events but miss the runheader the old has the runheader \n");
      if ( IsDebug() ) printf(" The run is already inserted \n");
      goto gonext;
    };
    //
    if ( glrun->GetPKT_COUNTER() && !(UInt_t)atoll(row->GetField(3)) ){  
      //
      if ( IsDebug() ) printf(" The new run has the same number of events, the runheader and the runtrailer the old one miss the runtrailer \n");
      //
      glrun->DeleteRun(conn,(UInt_t)atoll(row->GetField(0)),"GL_RUN");
      //       oss.str("");
      //       oss << "DELETE FROM GL_RUN WHERE ID=" << row->GetField(0) <<";";
      //       if ( IsDebug() ) printf(" delete the run entry: query is \n %s \n",oss.str().c_str());      
      //       conn->Query(oss.str().c_str());
      if ( signal ) signal = false;
      //
    };
    //
  gonext:
    // END PATCH!
    //
    row = result->Next();
    //
  };
  //
  delete result;
  //
  if ( signal && IsDebug() ) printf(" The run has already been inserted \n");    
  if ( !signal && IsDebug() ) printf(" The run existed and has been overridden, fill the DB \n");
  if ( PEDANTIC ) throw -86;
  return(signal);
};

/**
 * Handle runs which seems to be good ones.
 **/
void PamelaDBOperations::HandleRun(){  
  ULong64_t chkpkt = 0;  
  ULong64_t pktt = (ULong64_t)PKT(pht->GetCounter());
  ULong64_t pkth = (ULong64_t)PKT(phh->GetCounter());
  //
  chkpkt = pkth + (ULong64_t)runt->PKT_COUNTER + 1ULL + 1ULL;   
  //
  if ( labs(chkpkt-pktt)<2 ){ 
    //
    if ( IsDebug() ) printf(" check %llu pktt %llu \n",chkpkt,pktt); 
    //
    // it must be a good run, fill the db
    //
    this->FillClass();
    //
    if ( !IsRunAlreadyInserted() ){
      glrun->SetID(this->AssignRunID());
      glrun->SetID_RUN_FRAG(0);
      glrun->Fill_GL_RUN(conn);
    };
  } else {
    // 
    if ( IsDebug() ) printf(" oh no! the distance between runheader and runtrailer seems wrong: check %llu pktt %llu \n",chkpkt,pktt); 
    if ( IsDebug() ) printf(" try to recover run(s) without runheader and runtrailer between runheader and runtrailer\n"); 
    //
    this->HandleSuspiciousRun();
    //
  };
  //
  //
  return;
};


/**
 * Handle run fragments at the beginning or at the end of the file
 **/
void PamelaDBOperations::HandleRunFragments(Bool_t mishead, Bool_t mistrail, UInt_t firstev, UInt_t lastev){  
  //
  UInt_t rhfirstev = firstev;
  UInt_t rtlastev = lastev;
  Bool_t found = false;
  Bool_t foundinrun = false;
  //
  TSQLResult *result = 0;
  TSQLRow    *row    = 0;
  //
  stringstream oss;
  oss.str("");
  //
  // is the piece of run good (no other packets inside)?
  //
  if ( !this->IsRunConsistent(mishead,mistrail,firstev,lastev)){
    // 
    // if not, handle other pieces and continue with the first one
    //
    if ( IsDebug() ) printf("The run is not consistent, it contains non-physics packets! The run has been handled \n");
    //
  } else {
    //
    // we have now the good first piece of a run, fill the glrun object
    //
    if ( firstev != (lastev+1) ){ // could be a problem sometimes (?)
      if ( rhfirstev != firstev && !mishead ) mishead = true;
      if ( rtlastev != lastev && !mistrail ) mistrail = true;
    }; 
    //
    if ( IsDebug() ) printf(" bhere firstev is %i lastev is %i \n",firstev,lastev);
    this->FillClass(mishead,mistrail,firstev,lastev);
    if ( IsDebug() ) printf(" chere firstev is %i lastev is %i \n",firstev,lastev);
    //
    if ( IsDebug() ) printf("The run is good, is it the other piece in the GL_RUN_FRAGMENTS table?\n");
    if ( IsDebug() ) printf(" C THIS RUN: RUNHEADER_OBT %u RUNTRAILER_OBT %u RUNHEADER_PKT %u RUNTRAILER_PKT %u \n", glrun->GetRUNHEADER_OBT(),glrun->GetRUNTRAILER_OBT(),glrun->GetRUNHEADER_PKT(),glrun->GetRUNTRAILER_PKT());
    //
    // First of all insert the run in the fragment table...
    //
    oss.str("");
    oss << " SELECT ID FROM GL_RUN_FRAGMENTS WHERE "
	<< " BOOT_NUMBER=" << this->GetBOOTnumber() << " AND ("
	<< " (RUNHEADER_TIME>=" << (UInt_t)(glrun->GetRUNHEADER_TIME()-10) << " AND "
	<< " RUNTRAILER_TIME<=" << (UInt_t)(glrun->GetRUNTRAILER_TIME()+10) << " AND ("
	<< " RUNHEADER_OBT>=" << glrun->GetRUNHEADER_OBT() << " OR "
	<< " RUNHEADER_PKT>=" << glrun->GetRUNHEADER_PKT() << ") AND ("
	<< " RUNTRAILER_OBT<=" << glrun->GetRUNTRAILER_OBT() << " OR "
	<< " RUNTRAILER_PKT<=" << glrun->GetRUNTRAILER_PKT() << ") ) OR "
	<< " (RUNHEADER_TIME<=" << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "
	<< " RUNTRAILER_TIME>=" << (UInt_t)glrun->GetRUNTRAILER_TIME() <<" AND ("
	<< " RUNHEADER_OBT<=" << glrun->GetRUNHEADER_OBT() << " OR "
	<< " RUNHEADER_PKT<=" << glrun->GetRUNHEADER_PKT() << ") AND ("
	<< " RUNTRAILER_OBT>=" << glrun->GetRUNTRAILER_OBT() << " OR "
	<< " RUNTRAILER_PKT>=" << glrun->GetRUNTRAILER_PKT() << ") ));";
    //
    if ( IsDebug() ) printf(" check if run has been inserted: query is \n %s \n",oss.str().c_str());
    result = conn->Query(oss.str().c_str());
    //
    if ( !result ) throw -4;
    //
    row = result->Next();
    //
    if ( !row ){
      //
      // no, insert this run in the GL_RUN_FRAGMENTS table (check if exist before!)
      //
      if ( IsDebug() ) printf(" The run is new \n");
      if ( IsDebug() ) printf(" -> fill the GL_RUNFRAGMENTS table \n");
      //
      glrun->SetID(this->AssignRunID());
      glrun->SetID_RUN_FRAG(0);
      glrun->Fill_GL_RUN_FRAGMENTS(conn);
      //
    } else {
      if ( IsDebug() ) printf(" The run is already present in the fragment table, relaxed %u \n",RELAXED);
      if ( !RELAXED ){
	if ( PEDANTIC ) throw -69;
	return;
      } else {
	glrun->SetID((UInt_t)atoll(row->GetField(0)));
	glrun->SetID_RUN_FRAG(0);
      };
    };
    //
    if ( chewbacca && mishead && mistrail ) goto justcheck;
    //
    // can we find the other piece of the run in the GL_RUN_FRAGMENTS table?
    //    
    if ( mishead && ( rhfirstev == firstev || chewbacca ) ) { // look for runheader (only when at the beginning of the file, if at the end and the runh is 
      // missing it no way we can found a piece in the frag table
      //
      oss.str("");
      oss << " SELECT ID,TRK_CALIB_USED,RUNTRAILER_TIME,RUNTRAILER_OBT,RUNHEADER_PKT,RUNTRAILER_PKT FROM GL_RUN_FRAGMENTS WHERE "
	  << " BOOT_NUMBER=" << this->GetBOOTnumber() << " AND "
	  << " RUNHEADER_TIME <= " << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "
	  << " ID != " << glrun->ID 
	  << " ORDER BY RUNHEADER_TIME DESC LIMIT 1;"; // DESC NOT ASC!!
      //
      if ( IsDebug() ) printf(" look for runheader in the fragments table: query is \n %s \n",oss.str().c_str());
      result = conn->Query(oss.str().c_str());
      //
      if ( !result ) throw -4;
      //
      row = result->Next();
      //
      if ( !row && NoFrag() ){
	//
	oss.str("");
	oss << " SELECT ID,TRK_CALIB_USED,RUNTRAILER_TIME,RUNTRAILER_OBT,RUNHEADER_PKT,RUNTRAILER_PKT FROM GL_RUN WHERE "
	    << " BOOT_NUMBER=" << this->GetBOOTnumber() << " AND "
	    << " RUNHEADER_TIME <= " << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "
	    << " ID != " << glrun->ID 
	    << " AND ID=ID_RUN_FRAG ORDER BY RUNHEADER_TIME DESC LIMIT 1;"; // DESC NOT ASC!!
	//
	if ( IsDebug() ) printf(" look for runheader in the GL_RUN table: query is \n %s \n",oss.str().c_str());
	result = conn->Query(oss.str().c_str());
	//
	if ( !result ) throw -4;
	//
	foundinrun = true;
	//
	row = result->Next();
	//
      };
      //
      if ( !row ){
	if ( IsDebug() ) printf(" the corresponding piece has NOT been found \n");
	found = false;
      } else {
	//
	found = false; // default value
	//
	if ( IsDebug() ) printf(" A Found a possible candidate, checking if it is the good one... \n");
	//
	// if we have both runheader and runtrailer we can check with pkt_counter:
	//
	if ( !mistrail && (UInt_t)atoll(row->GetField(1)) != 0 ){
	  ULong64_t chkpkt = 0;  
	  ULong64_t pktt = (ULong64_t)PKT(glrun->GetRUNTRAILER_PKT());
	  ULong64_t pkth = (ULong64_t)PKT((UInt_t)atoll(row->GetField(4)));
	  //
	  chkpkt = pkth + (ULong64_t)glrun->GetPKT_COUNTER() + 1ULL + 1ULL;   
	  //
	  if ( labs(chkpkt-pktt)<2 ){ 
	    //
	    if ( IsDebug() ) printf(" FOUND!!! check %llu pktt %llu \n",chkpkt,pktt); 
	    //
	    found = true;
	    if ( IsDebug() ) printf(" where firstev is %i lastev is %i \n",firstev,lastev);
	    //
	  } else {
	    //
	    if ( IsDebug() ) printf(" The check with pkt counter failed: check %llu pktt %llu \n",chkpkt,pktt); 	    
	    //
	    found = false;
	    //
	  };
	};
	if ( !found && chewbacca ) goto justcheck;
	if ( !found ){
	  //
	  // if we arrive here we were not able to decide if the two pieces matches using only the pkt counter information, we must check times and obts
	  //
	  ULong64_t chkpkt1 = 0;
	  ULong64_t orunh1 = (ULong64_t)PKT(glrun->GetRUNHEADER_PKT());
	  ULong64_t dbrunt1 = (ULong64_t)PKT((UInt_t)atoll(row->GetField(5)));
	  chkpkt1 = labs(orunh1-dbrunt1);
	  //
	  ULong64_t chkpkt2 = 0;
	  ULong64_t orunh2 = (ULong64_t)OBT(glrun->GetRUNHEADER_OBT());
	  ULong64_t dbrunt2 = (ULong64_t)OBT((UInt_t)atoll(row->GetField(3)));
	  chkpkt2 = labs(orunh2-dbrunt2);
	  //
	  ULong64_t chkpkt3 = 0;
	  ULong64_t orunh3 = (ULong64_t)(glrun->GetRUNHEADER_TIME());
	  ULong64_t dbrunt3 = (ULong64_t)((UInt_t)atoll(row->GetField(2)));
	  chkpkt3 = labs(orunh3-dbrunt3);
	  //
	  if ( (chkpkt1 < 200 || chkpkt2 < 20000) && chkpkt3 < 20 ){
	    //	if ( chkpkt1 < 100 && chkpkt2 < 30000 && chkpkt3 < 30 ){
	    //
	    if ( IsDebug() ) printf(" FOUND!!! check1 %llu<200 cechk2 %llu<20000 check3 %llu<20 \n",chkpkt1,chkpkt2,chkpkt3); 
	    //
	    found = true;
	    //
	  } else {
	    //
	    if ( IsDebug() ) printf(" Check failed: check1 %llu<200? cechk2 %llu<20000? check3 %llu<20? \n",chkpkt1,chkpkt2,chkpkt3); 
	    //
	    found = false;
	    //
	  };
	};
      };
      //
      if ( found ){
	// 
	// we have found the missing piece, glue the two together, merge the informations, fill the gl_run table (check first runs do not exists), delete entry in frag table
	// 
	if ( IsDebug() ) printf(" now you can handle the piece of the run \n "); 
	//
	if ( foundinrun ){
	  glrun->RestoreRun(conn,(UInt_t)atoll(row->GetField(0)),"GL_RUN_FRAGMENTS");
	  glrun->DeleteRun(conn,(UInt_t)atoll(row->GetField(0)),"GL_RUN");
	};
	//
	GL_RUN *glrun1 = new GL_RUN();
	//
	//      UInt_t idfrag = (UInt_t)atoll(row->GetField(0));
	//
	oss.str("");
	oss << " ID="<<row->GetField(0)<<";";
	//
	glrun1->Query_GL_RUN_FRAGMENTS(oss.str().c_str(),conn); // here we have runheader infos
	if ( IsDebug() ) printf(" there firstev is %i lastev is %i \n",firstev,lastev);
	//
	// merge infos
	//
	UInt_t apkt = PKT(glrun1->GetRUNTRAILER_PKT());
	ULong64_t aobt = OBT(glrun1->GetRUNTRAILER_OBT());
	UInt_t bpkt = PKT(glrun->GetRUNHEADER_PKT());
	ULong64_t bobt = OBT(glrun->GetRUNHEADER_OBT());
	if ( IsDebug() ) printf(" Check overlapping events: %u %u %llu %llu firstev is %i\n",apkt,bpkt,aobt,bobt,firstev);
	TTree *T= 0;
	T = (TTree*)file->Get("Physics");
	if ( !T || T->IsZombie() ) throw -16;
	EventHeader *eh = 0;
	PscuHeader *ph = 0;
	T->SetBranchAddress("Header", &eh);
	while ( apkt > bpkt && aobt > bobt && firstev < lastev ){
	  T->GetEntry(firstev);
	  ph = eh->GetPscuHeader();
	  bpkt = PKT(ph->GetCounter());
	  bobt = OBT(ph->GetOrbitalTime());	
	  firstev++;
	  if ( PEDANTIC ) throw -71;
	};
	if ( IsDebug() ) printf(" Check overlapping events done: %u %u %llu %llu firstev is %i\n",apkt,bpkt,aobt,bobt,firstev);
	//
	glrun1->SetPKT_COUNTER(glrun->GetPKT_COUNTER());
	glrun1->SetPKT_READY_COUNTER(glrun->GetPKT_READY_COUNTER());
	glrun1->SetRUNTRAILER_TIME(glrun->GetRUNTRAILER_TIME());
	glrun1->SetRUNTRAILER_OBT(glrun->GetRUNTRAILER_OBT());
	glrun1->SetRUNTRAILER_PKT(glrun->GetRUNTRAILER_PKT());
	//
	if ( IsDebug() ) printf(" here firstev is %i lastev is %i \n",firstev,lastev);
	//
	glrun->SetEV_FROM(firstev);
	glrun->SetEV_TO(lastev); // EM 10 RED ghost run bug
	glrun->SetNEVENTS(lastev-firstev+1);
	//
	glrun->SetRUNHEADER_TIME(glrun1->GetRUNHEADER_TIME());
	glrun->SetRUNHEADER_OBT(glrun1->GetRUNHEADER_OBT());
	glrun->SetRUNHEADER_PKT(glrun1->GetRUNHEADER_PKT());
	glrun->SetCOMPILATIONTIMESTAMP(glrun1->GetCOMPILATIONTIMESTAMP());
	glrun->SetFAV_WRK_SCHEDULE(glrun1->GetFAV_WRK_SCHEDULE());
	glrun->SetEFF_WRK_SCHEDULE(glrun1->GetEFF_WRK_SCHEDULE());
	glrun->SetPRH_VAR_TRG_MODE_A(glrun1->GetPRH_VAR_TRG_MODE_A());
	glrun->SetPRH_VAR_TRG_MODE_B(glrun1->GetPRH_VAR_TRG_MODE_B());
	glrun->SetACQ_BUILD_INFO(glrun1->GetACQ_BUILD_INFO());
	glrun->SetACQ_VAR_INFO(glrun1->GetACQ_VAR_INFO());
	glrun->SetRM_ACQ_AFTER_CALIB(glrun1->GetRM_ACQ_AFTER_CALIB());  
	glrun->SetRM_ACQ_SETTING_MODE(glrun1->GetRM_ACQ_SETTING_MODE());  
	glrun->SetTRK_CALIB_USED(glrun1->GetTRK_CALIB_USED());  
	glrun->SetCAL_DSP_MASK(glrun1->GetCAL_DSP_MASK());  
	glrun->SetLAST_TIMESYNC(glrun1->GetLAST_TIMESYNC());  
	glrun->SetOBT_TIMESYNC(glrun1->GetOBT_TIMESYNC());  
	//
	if ( glrun1->GetPHYSENDRUN_MASK_S3S2S12() ) glrun->SetPHYSENDRUN_MASK_S3S2S12(glrun1->GetPHYSENDRUN_MASK_S3S2S12());
	if ( glrun1->GetPHYSENDRUN_MASK_S11CRC() ) glrun->SetPHYSENDRUN_MASK_S11CRC(glrun1->GetPHYSENDRUN_MASK_S11CRC());
	//
	if ( !IsRunAlreadyInserted() ){
	  //
	  //	glrun->SetID(this->AssignRunID());
	  glrun->SetID_RUN_FRAG(glrun1->GetID());
	  glrun->Fill_GL_RUN(conn);
	  //
	  // set id number
	  //
	  glrun1->SetID_RUN_FRAG(glrun->GetID());
	  glrun1->Fill_GL_RUN(conn);
	  //
	};
	// delete old entry in fragment table
	//
	glrun->DeleteRun(conn,0,"GL_RUN_FRAGMENTS");
	glrun1->DeleteRun(conn,0,"GL_RUN_FRAGMENTS");
	//
	delete glrun1;
	//
	//
	return;
	//
      };
      //
    };
    //
    if ( mistrail && ( rtlastev == lastev || chewbacca )) { // look for runtrailer (only when at the end of the file, if at the beginning and the runh is 
      // missing it no way we can found a piece in the frag table
      //
      oss.str("");
      oss << " SELECT ID,PKT_COUNTER,RUNHEADER_TIME,RUNHEADER_OBT,RUNTRAILER_PKT,RUNHEADER_PKT FROM GL_RUN_FRAGMENTS WHERE "
	  << " BOOT_NUMBER=" << this->GetBOOTnumber() << " AND "
	  << " RUNTRAILER_TIME >= " << (UInt_t)glrun->GetRUNTRAILER_TIME() << " AND "
	  << " ID != " << glrun->ID 
	  << " ORDER BY RUNTRAILER_TIME ASC LIMIT 1;";
      //
      if ( IsDebug() ) printf(" look for runtrailer in the fragments table: query is \n %s \n",oss.str().c_str());
      result = conn->Query(oss.str().c_str());
      //
      if ( !result ) throw -4;
      //
      row = result->Next();
      //
      if ( !row && NoFrag() ){
	//
	oss.str("");
	oss << " SELECT ID,PKT_COUNTER,RUNHEADER_TIME,RUNHEADER_OBT,RUNTRAILER_PKT,RUNHEADER_PKT FROM GL_RUN WHERE "
	    << " BOOT_NUMBER=" << this->GetBOOTnumber() << " AND "
	    << " RUNTRAILER_TIME >= " << (UInt_t)glrun->GetRUNTRAILER_TIME() << " AND "
	    << " ID != " << glrun->ID 
	    << " AND ID=ID_RUN_FRAG ORDER BY RUNTRAILER_TIME ASC LIMIT 1;";
	//
	if ( IsDebug() ) printf(" look for runheader in the GL_RUN table: query is \n %s \n",oss.str().c_str());
	result = conn->Query(oss.str().c_str());
	//
	if ( !result ) throw -4;
	//
	foundinrun = true;
	row = result->Next();
	//
      };
      //
      if ( !row ){
	if ( IsDebug() ) printf(" the corresponding piece has NOT been found \n");
	found = false;
      } else {
	//
	found = false; // default value
	//
	if ( IsDebug() ) printf(" B Found a possible candidate, checking if it is the good one... \n");
	//
	// if we have both runheader and runtrailer we can check with pkt_counter:
	//
	if ( !mishead && (UInt_t)atoll(row->GetField(1)) != 0 ){
	  ULong64_t chkpkt = 0;  
	  ULong64_t pktt = (ULong64_t)PKT((UInt_t)atoll(row->GetField(4)));
	  ULong64_t pkth = (ULong64_t)PKT(glrun->GetRUNHEADER_PKT());
	  //
	  chkpkt = pkth + (ULong64_t)((UInt_t)atoll(row->GetField(1))) + 1ULL + 1ULL;   
	  //
	  if ( labs(chkpkt-pktt)<2 ){ 
	    //
	    if ( IsDebug() ) printf(" FOUND!!! check %llu pktt %llu \n",chkpkt,pktt); 
	    //
	    found = true;
	    //
	  } else {
	    //
	    if ( IsDebug() ) printf(" The check with pkt counter failed: check %llu pktt %llu \n",chkpkt,pktt); 	    
	    //
	    found = false;
	    //
	  };
	};
	if ( !found && chewbacca ) goto justcheck;
	if ( !found ){
	  //
	  // if we arrive here we were not able to decide if the two pieces matches using only the pkt counter information, we must check times and obts
	  //
	  ULong64_t chkpkt1 = 0;
	  ULong64_t orunh1 = (ULong64_t)PKT(glrun->GetRUNTRAILER_PKT());
	  ULong64_t dbrunt1 = (ULong64_t)PKT((UInt_t)atoll(row->GetField(5)));
	  chkpkt1 = labs(orunh1-dbrunt1);
	  //
	  ULong64_t chkpkt2 = 0;
	  ULong64_t orunh2 = (ULong64_t)OBT(glrun->GetRUNTRAILER_OBT());
	  ULong64_t dbrunt2 = (ULong64_t)OBT((UInt_t)atoll(row->GetField(3)));
	  chkpkt2 = labs(orunh2-dbrunt2);
	  //
	  ULong64_t chkpkt3 = 0;
	  ULong64_t orunh3 = (ULong64_t)(glrun->GetRUNTRAILER_TIME());
	  ULong64_t dbrunt3 = (ULong64_t)((UInt_t)atoll(row->GetField(2)));
	  chkpkt3 = labs(orunh3-dbrunt3);
	  //
	  if ( (chkpkt1 < 200 || chkpkt2 < 20000) && chkpkt3 < 20 ){
	    //
	    if ( IsDebug() ) printf(" FOUND!!! check1 %llu<200 cechk2 %llu<20000 check3 %llu<20 \n",chkpkt1,chkpkt2,chkpkt3); 
	    //
	    found = true;
	    //
	  } else {
	    //
	    if ( IsDebug() ) printf(" Check failed: check1 %llu<200? cechk2 %llu<20000? check3 %llu<20? \n",chkpkt1,chkpkt2,chkpkt3); 
	    //
	    found = false;
	    //
	  };
	};
      };
      //
      if ( found ){
	// 
	// we have found the missing piece, glue the two together, merge the informations, fill the gl_run table (check first runs do not exists), delete entry in frag table
	// 
	if ( IsDebug() ) printf(" now you can handle the piece of the run \n "); 
	//
	if ( foundinrun ){
	  glrun->RestoreRun(conn,(UInt_t)atoll(row->GetField(0)),"GL_RUN_FRAGMENTS");
	  glrun->DeleteRun(conn,(UInt_t)atoll(row->GetField(0)),"GL_RUN");
	};
	//
	GL_RUN *glrun1 = new GL_RUN();
	//
	//      UInt_t idfrag = (UInt_t)atoll(row->GetField(0));
	//
	oss.str("");
	oss << " ID="<<row->GetField(0)<<";";
	//
	glrun1->Query_GL_RUN_FRAGMENTS(oss.str().c_str(),conn); // here we have runtrailer infos
	//
	// merge infos
	//
	UInt_t apkt = PKT(glrun->GetRUNTRAILER_PKT());
	ULong64_t aobt = OBT(glrun->GetRUNTRAILER_OBT());
	UInt_t bpkt = PKT(glrun1->GetRUNHEADER_PKT());
	ULong64_t bobt = OBT(glrun1->GetRUNHEADER_OBT());
	if ( IsDebug() ) printf(" Check overlapping events: %u %u %llu %llu lastev is %i\n",apkt,bpkt,aobt,bobt,lastev);
	TTree *T= 0;
	T = (TTree*)file->Get("Physics");
	if ( !T || T->IsZombie() ) throw -16;
	EventHeader *eh = 0;
	PscuHeader *ph = 0;
	T->SetBranchAddress("Header", &eh);
	while ( apkt > bpkt && aobt > bobt && lastev > 0 ){
	  T->GetEntry(lastev);
	  ph = eh->GetPscuHeader();
	  apkt = PKT(ph->GetCounter());
	  aobt = OBT(ph->GetOrbitalTime());	
	  lastev--;
	  if ( PEDANTIC && !RELAXED) throw -72;
	};
	if ( IsDebug() ) printf(" Check overlapping events done: %u %u %llu %llu lastev is %i\n",apkt,bpkt,aobt,bobt,lastev);
	//
	glrun->SetEV_FROM(firstev); // EM 10RED ghost run bug
	glrun->SetEV_TO(lastev);
	glrun->SetNEVENTS(lastev-firstev+1);
	glrun->SetPKT_COUNTER(glrun1->GetPKT_COUNTER());
	glrun->SetPKT_READY_COUNTER(glrun1->GetPKT_READY_COUNTER());
	glrun->SetRUNTRAILER_TIME(glrun1->GetRUNTRAILER_TIME());
	glrun->SetRUNTRAILER_OBT(glrun1->GetRUNTRAILER_OBT());
	glrun->SetRUNTRAILER_PKT(glrun1->GetRUNTRAILER_PKT());
	//
	glrun1->SetRUNHEADER_TIME(glrun->GetRUNHEADER_TIME());
	glrun1->SetRUNHEADER_OBT(glrun->GetRUNHEADER_OBT());
	glrun1->SetRUNHEADER_PKT(glrun->GetRUNHEADER_PKT());
	glrun1->SetCOMPILATIONTIMESTAMP(glrun->GetCOMPILATIONTIMESTAMP());
	glrun1->SetFAV_WRK_SCHEDULE(glrun->GetFAV_WRK_SCHEDULE());
	glrun1->SetEFF_WRK_SCHEDULE(glrun->GetEFF_WRK_SCHEDULE());
	glrun1->SetPRH_VAR_TRG_MODE_A(glrun->GetPRH_VAR_TRG_MODE_A());
	glrun1->SetPRH_VAR_TRG_MODE_B(glrun->GetPRH_VAR_TRG_MODE_B());
	glrun1->SetACQ_BUILD_INFO(glrun->GetACQ_BUILD_INFO());
	glrun1->SetACQ_VAR_INFO(glrun->GetACQ_VAR_INFO());
	glrun1->SetRM_ACQ_AFTER_CALIB(glrun->GetRM_ACQ_AFTER_CALIB());  
	glrun1->SetRM_ACQ_SETTING_MODE(glrun->GetRM_ACQ_SETTING_MODE());  
	glrun1->SetTRK_CALIB_USED(glrun->GetTRK_CALIB_USED());  
	glrun1->SetCAL_DSP_MASK(glrun->GetCAL_DSP_MASK());  
	glrun1->SetLAST_TIMESYNC(glrun->GetLAST_TIMESYNC());  
	glrun1->SetOBT_TIMESYNC(glrun->GetOBT_TIMESYNC());  
	//
	if ( glrun->GetPHYSENDRUN_MASK_S3S2S12() ) glrun1->SetPHYSENDRUN_MASK_S3S2S12(glrun->GetPHYSENDRUN_MASK_S3S2S12());
	if ( glrun->GetPHYSENDRUN_MASK_S11CRC() ) glrun1->SetPHYSENDRUN_MASK_S11CRC(glrun->GetPHYSENDRUN_MASK_S11CRC());
	//
	if ( !IsRunAlreadyInserted() ){
	  //
	  //	glrun->SetID(this->AssignRunID());
	  //
	  glrun->SetID_RUN_FRAG(glrun1->GetID());
	  glrun->Fill_GL_RUN(conn);
	  //
	  // set id number
	  //
	  glrun1->SetID_RUN_FRAG(glrun->GetID());
	  glrun1->Fill_GL_RUN(conn);
	  //
	};
	//
	// delete old entries in fragment table
	//
	glrun->DeleteRun(conn,0,"GL_RUN_FRAGMENTS");
	glrun1->DeleteRun(conn,0,"GL_RUN_FRAGMENTS");
	//
	delete glrun1;
	//
	return;
	//
      };
      //
    };
    //
  justcheck:
    //
    if ( !found ){      
      //
      if ( IsDebug() ) printf(" not found, check if we have already processed the file \n "); 
      //
      // not found, has this run already inserted in the GL_RUN or in the GL_RUN_FRAGMENTS table?
      //
      oss.str("");
      oss << " SELECT ID,ID_ROOT_L0 FROM GL_RUN WHERE "
	  << " BOOT_NUMBER=" << this->GetBOOTnumber() << " AND ("
	  << " (RUNHEADER_TIME>=" << (UInt_t)(glrun->GetRUNHEADER_TIME()-10) << " AND "
	  << " RUNTRAILER_TIME<=" << (UInt_t)(glrun->GetRUNTRAILER_TIME()+10) << " AND ("
	  << " RUNHEADER_OBT>=" << glrun->GetRUNHEADER_OBT() << " OR "
	  << " RUNHEADER_PKT>=" << glrun->GetRUNHEADER_PKT() << ") AND ("
	  << " RUNTRAILER_OBT<=" << glrun->GetRUNTRAILER_OBT() << " OR "
	  << " RUNTRAILER_PKT<=" << glrun->GetRUNTRAILER_PKT() << ") ) OR "
	  << " (RUNHEADER_TIME<=" << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "
	  << " RUNTRAILER_TIME>=" << (UInt_t)glrun->GetRUNTRAILER_TIME() <<" AND ("
	  << " RUNHEADER_OBT<=" << glrun->GetRUNHEADER_OBT() << " OR "
	  << " RUNHEADER_PKT<=" << glrun->GetRUNHEADER_PKT() << ") AND ("
	  << " RUNTRAILER_OBT>=" << glrun->GetRUNTRAILER_OBT() << " OR "
	  << " RUNTRAILER_PKT>=" << glrun->GetRUNTRAILER_PKT() << ") ));";
      //
      if ( IsDebug() ) printf(" check if run has been inserted: query is \n %s \n",oss.str().c_str());
      result = conn->Query(oss.str().c_str());
      //
      if ( !result ) throw -4;
      //
      row = result->Next();
      //
      if ( row ){
	//
	// we end up here if chewbacca and we have RH---| small gap |---RT, in this case the two pieces are attached and moved to GL_RUN. We are now processing the 
	// "small gap" piece... we recognize this since: we have two entries from this query, the pkt number is consistent with our pkt number.
	//
	// 090112 [8RED (-70): RUN ALREADY INSERTED]
	// 093012 [8RED (-70): RUN ALREADY INSERTED] try to be more general... the run has not been instered yet if the runheader-trailer PKT interval is not covered by already inserted runs, NOTICE: we must look in the GL_RUN_TRASH table!
	//
	Bool_t OK = false;
	UInt_t IDRL2A = 0;
	UInt_t IDRL2B = 0;
	if ( chewbacca ){
	  if ( result->GetRowCount() >= 2 ){
	    //
	    if ( IsDebug() ) printf(" RH---| gap |---RT case, number of pieces in the GL_RUN table: %i \n",result->GetRowCount());
	    OK = true;
	    IDRL2A = (UInt_t)atoll(row->GetField(0));
	    //
	    while ( row ){
	      //
	      TSQLResult *trresult = 0;
	      TSQLRow    *trrow    = 0;
	      //
	      stringstream tross;
	      tross.str("");
	      //
	      tross << " SELECT RUNHEADER_PKT, RUNTRAILER_PKT FROM GL_RUN_TRASH where ID=" << row->GetField(0) << ";";
	      if ( IsDebug() ) printf(" check in the gl_run_trash table for pkt intervals: query is \n %s \n",tross.str().c_str());
	      trresult = conn->Query(tross.str().c_str());
	      if ( !trresult ) throw -4;
	      trrow = trresult->Next();
	      if ( !trrow || trresult->GetRowCount() != 1 ){
		OK = false;
		if ( IsDebug() ) printf(" OPS! no such run (or multiple runs!) in GL_RUN_TRASH table, something wrong is going on! \n");
		break;
	      };
	      //
	      UInt_t pktH =  (UInt_t)atoll(row->GetField(0));
	      UInt_t pktT =  (UInt_t)atoll(row->GetField(1));
	      delete trresult;
	      if (
		  (PKT(pktH) >= PKT(glrun->GetRUNHEADER_PKT()) && PKT(pktH) <= PKT(glrun->GetRUNTRAILER_PKT())) ||
		  (PKT(pktT) >= PKT(glrun->GetRUNHEADER_PKT()) && PKT(pktT) <= PKT(glrun->GetRUNTRAILER_PKT())) ||
		  (PKT(pktH) <= PKT(glrun->GetRUNTRAILER_PKT()) && PKT(pktT) >= PKT(glrun->GetRUNTRAILER_PKT())) ){	       
		OK = false;
		if ( IsDebug() ) printf(" The run is overlapping with already inserted ones!! \n");
		break;		
	      };
	      //PKT(glrun->GetRUNHEADER_PKT())  PKT(glrun->GetRUNTRAILER_PKT())
	      row = result->Next();
	    };
	    
	    //	  if ( result->GetRowCount() == 2 ) {
	    // 	    IDRL2A = (UInt_t)atoll(row->GetField(0));
	    // 	    UInt_t IDRL0A = (UInt_t)atoll(row->GetField(1));
	    // 	    row = result->Next();
	    // 	    IDRL2B = (UInt_t)atoll(row->GetField(0));
	    // 	    UInt_t IDRL0B = (UInt_t)atoll(row->GetField(1));
	    // 	    if ( IsDebug() ) printf(" IDRL0A %u B %u IDRL2A %u B %u \n",IDRL0A,IDRL0B,IDRL2A,IDRL2B);
	    // 	    //	    if ( IDRL0A == IDRL0B ){ //091230 why this condition???? RH could be in a file and RT in another one...
	    // 	    if ( true ){
	    // 	      TSQLResult *result2 = 0;
	    // 	      TSQLRow    *row2    = 0;
	    // 	      oss.str("");
	    // 	      oss << "select PKT_NUMBER_FINAL from ROOT_TABLE_MERGING where REAL_TIME_INIT<" << chrtinit << " order by REAL_TIME_INIT desc limit 1;";
	    // 	      if ( IsDebug() ) printf(" Check if we are in the case RH---| small gap |---RT: query is \n %s \n",oss.str().c_str());
	    // 	      result2 = conn->Query(oss.str().c_str());
	    // 	      //
	    // 	      if ( !result2 ) throw -4;
	    // 	      //
	    // 	      row2 = result2->Next();
	    // 	      //
	    // 	      if ( row2 ){
	    // 		UInt_t PKA = (UInt_t)atoll(row2->GetField(0));
	    // 		delete result2;
	    // 		oss.str("");
	    // 		oss << "select PKT_NUMBER_INIT from ROOT_TABLE_MERGING where REAL_TIME_INIT>" << chrtinit << " order by REAL_TIME_INIT asc limit 1;";
	    // 		if ( IsDebug() ) printf(" Check if we are in the case RH---| small gap |---RT: query is \n %s \n",oss.str().c_str());
	    // 		result2 = conn->Query(oss.str().c_str());
	    // 		//
	    // 		if ( !result2 ) throw -4;
	    // 		//
	    // 		row2 = result2->Next();
	    // 		//
	    // 		if ( row2 ){
	    // 		  UInt_t PKB = (UInt_t)atoll(row2->GetField(0));
	    // 		  //
	    // 		  if ( IsDebug() ) printf(" PKT(PKA) + 1 %llu == runheaderpkt %llu && PKB = runtrailer %llu + 1 %llu \n",PKT(PKA)+1LL, PKT(glrun->GetRUNHEADER_PKT()),PKT(PKB), PKT(glrun->GetRUNTRAILER_PKT())+1LL);
	    // 		  if ( PKT(PKA)+1LL == PKT(glrun->GetRUNHEADER_PKT()) && PKT(PKB) == PKT(glrun->GetRUNTRAILER_PKT())+1LL ){
	    // 		    if ( IsDebug() ) printf(" Ok, we are in the case: RH---| small gap |---RT \n");
	    // 		    OK = true;
	    // 		  };
	    // 		};
	    // 	      };		  
	    // 	    };
	    // 	  };	  
	  };
	};
	if ( OK ){
	  //
	  // this is the case in which we must insert a piece of run between two fragments in the GL_RUN table // we arrive here ONLY with internal pieces of runs, never runheader or runtrailer by definition	  
	  //
	  // we have to update with runheader/trailer infos our run and we have to change the ROOT_ID_FRAG of the header piece ( 1/2 2/1 must become 1/3 3/2 2/1 )
	  //
	  if ( IsDebug() ) printf(" Ok, we are in the case: RH---| small gap |---RT \n");
	  //
	  GL_RUN *glA = new GL_RUN();
	  glA->Query_GL_RUN(IDRL2A,conn);
	  //
	  glrun->SetRUNHEADER_TIME(glA->GetRUNHEADER_TIME());
	  glrun->SetRUNHEADER_OBT(glA->GetRUNHEADER_OBT());
	  glrun->SetRUNHEADER_PKT(glA->GetRUNHEADER_PKT());
	  //
	  glrun->SetRUNTRAILER_TIME(glA->GetRUNTRAILER_TIME());
	  glrun->SetRUNTRAILER_OBT(glA->GetRUNTRAILER_OBT());
	  glrun->SetRUNTRAILER_PKT(glA->GetRUNTRAILER_PKT());
	  //
	  if ( glA->GetPHYSENDRUN_MASK_S3S2S12() ) glrun->SetPHYSENDRUN_MASK_S3S2S12(glA->GetPHYSENDRUN_MASK_S3S2S12());
	  if ( glA->GetPHYSENDRUN_MASK_S11CRC() ) glrun->SetPHYSENDRUN_MASK_S11CRC(glA->GetPHYSENDRUN_MASK_S11CRC());
	  //	      
	  if ( glA->GetACQ_BUILD_INFO() != 0 ){
	    //
	    // the first piece contains a good runheader we can update all the other runs with correct infos!
	    //
	    glrun->SetCOMPILATIONTIMESTAMP(glA->GetCOMPILATIONTIMESTAMP());
	    glrun->SetFAV_WRK_SCHEDULE(glA->GetFAV_WRK_SCHEDULE());
	    glrun->SetEFF_WRK_SCHEDULE(glA->GetEFF_WRK_SCHEDULE());
	    glrun->SetPRH_VAR_TRG_MODE_A(glA->GetPRH_VAR_TRG_MODE_A());
	    glrun->SetPRH_VAR_TRG_MODE_B(glA->GetPRH_VAR_TRG_MODE_B());
	    glrun->SetACQ_BUILD_INFO(glA->GetACQ_BUILD_INFO());
	    glrun->SetACQ_VAR_INFO(glA->GetACQ_VAR_INFO());
	    glrun->SetRM_ACQ_AFTER_CALIB(glA->GetRM_ACQ_AFTER_CALIB());
	    glrun->SetRM_ACQ_SETTING_MODE(glA->GetRM_ACQ_SETTING_MODE());
	    glrun->SetTRK_CALIB_USED(glA->GetTRK_CALIB_USED());
	    glrun->SetCAL_DSP_MASK(glA->GetCAL_DSP_MASK());
	    glrun->SetLAST_TIMESYNC(glA->GetLAST_TIMESYNC());
	    glrun->SetOBT_TIMESYNC(glA->GetOBT_TIMESYNC());
	    //
	  };
	  //
	  if ( glA->GetPKT_READY_COUNTER() != 0 ){
	    //
	    // the first piece contains a good runtrailer we can update all the other runs with correct infos!
	    //
	    glrun->SetPKT_COUNTER(glA->GetPKT_COUNTER());
	    glrun->SetPKT_READY_COUNTER(glA->GetPKT_READY_COUNTER());
	  };
	  //
	  // update runheader ROOT_ID_FRAG
	  //
	  oss.str("");
	  oss << "UPDATE GL_RUN SET ID_RUN_FRAG = " << glrun->GetID() << " where ID = " << IDRL2A << ";";
	  if ( IsDebug() ) printf(" update gl_run to have cross indexing: %s\n",oss.str().c_str());
	  conn->Query(oss.str().c_str());
	  //
	  oss.str("");
	  oss << "SELECT ID FROM GL_RUN WHERE ID_RUN_FRAG = " << IDRL2A << ";";
	  if ( IsDebug() ) printf(" update gl_run to have cross indexing: %s\n",oss.str().c_str());
	  TSQLResult *tsresult = 0;
	  TSQLRow    *tsrow    = 0;
	  tsresult=conn->Query(oss.str().c_str());
	  if ( !tsresult ) throw -4;
	  tsrow = tsresult->Next();
	  if ( !tsrow || tsresult->GetRowCount() != 1 ) throw -4;
	  IDRL2B = (UInt_t)atoll(tsrow->GetField(0));
	  glrun->SetID_RUN_FRAG(IDRL2B);
	  //
	  // fill the new run in GL_RUN
	  //
	  glrun->Fill_GL_RUN(conn);	
	  //
	  glrun->DeleteRun(conn,0,"GL_RUN_FRAGMENTS");
	  delete glA;
	  //
	} else {
// 	  //
// 	  // this is the case in which we must insert a piece of run between two fragments in the GL_RUN table
// 	  //
// 	  // we have to update with runheader/trailer infos our run and we have to change the ROOT_ID_FRAG of the header piece ( 1/2 2/1 must become 1/3 3/2 2/1 )
// 	  //
// 	  GL_RUN *glA = new GL_RUN();
// 	  glA->Query_GL_RUN(IDRL2A,conn);
// 	  //
// 	  if ( glA->GetACQ_BUILD_INFO() != 0 ){
// 	    //
// 	    // the first piece contains a good runheader we can update all the other runs with correct infos!
// 	    //
// 	    oss.str("");
// 	    oss << "UPDATE GL_RUN_FRAGMENTS SET "
// 		<< " RUNHEADER_TIME=" << glA->GetRUNHEADER_TIME()<< " , "
// 		<< " RUNHEADER_OBT=" << glA->GetRUNHEADER_OBT()<< " , "
// 		<< " RUNHEADER_PKT=" << glA->GetRUNHEADER_PKT()<< " , "
// 		<< " COMPILATIONTIMESTAMP=" << glA->GetCOMPILATIONTIMESTAMP()<< " , "
// 		<< " FAV_WRK_SCHEDULE=" << glA->GetFAV_WRK_SCHEDULE()<< " , "
// 		<< " EFF_WRK_SCHEDULE=" << glA->GetEFF_WRK_SCHEDULE()<< " , "
// 		<< " PRH_VAR_TRG_MODE_A=" << glA->GetPRH_VAR_TRG_MODE_A()<< " , "
// 		<< " PRH_VAR_TRG_MODE_B=" << glA->GetPRH_VAR_TRG_MODE_B()<< " , "
// 		<< " ACQ_BUILD_INFO=" << glA->GetACQ_BUILD_INFO()<< " , "
// 		<< " ACQ_VAR_INFO=" << glA->GetACQ_VAR_INFO()<< " , "
// 		<< " RM_ACQ_AFTER_CALIB=" << glA->GetRM_ACQ_AFTER_CALIB()<< " , "  
// 		<< " RM_ACQ_SETTING_MODE=" << glA->GetRM_ACQ_SETTING_MODE()<< " , "  
// 		<< " TRK_CALIB_USED=" << glA->GetTRK_CALIB_USED()<< " , "  
// 		<< " CAL_DSP_MASK=" << glA->GetCAL_DSP_MASK()<< " , "  
// 		<< " LAST_TIMESYNC=" << glA->GetLAST_TIMESYNC()<< " , ";
// 	    //
// 	    if ( glA->GetPHYSENDRUN_MASK_S3S2S12() )
// 	      oss << " PHYSENDRUN_MASK_S3S2S12=" << glA->GetPHYSENDRUN_MASK_S3S2S12() << " , "; 
// 	    if ( glA->GetPHYSENDRUN_MASK_S11CRC() )
// 	      oss << " PHYSENDRUN_MASK_S11CRC=" << glA->GetPHYSENDRUN_MASK_S11CRC() << " , ";
// 	    //	      
// 	    oss << " OBT_TIMESYNC=" << glA->GetOBT_TIMESYNC();
// 	    oss << " WHERE ID=" << glrun->GetID() << ";";
// 	    if ( IsDebug() ) printf(" update with correct infos: %s\n",oss.str().c_str());
// 	    conn->Query(oss.str().c_str());	
// 	    //
// 	  } else {
// 	    //
// 	    // sig no runheader, let set anyway what is possible...
// 	    //
// 	    oss.str("");
// 	    oss << "UPDATE GL_RUN_FRAGMENTS SET "
// 		<< " RUNHEADER_TIME=" << glA->GetRUNHEADER_TIME()<< " , ";
// 	    //
// 	    if ( glA->GetPHYSENDRUN_MASK_S3S2S12() )
// 	      oss << " PHYSENDRUN_MASK_S3S2S12=" << glA->GetPHYSENDRUN_MASK_S3S2S12()<< " , ";
// 	    if ( glA->GetPHYSENDRUN_MASK_S11CRC() )
// 	      oss << " PHYSENDRUN_MASK_S11CRC=" << glA->GetPHYSENDRUN_MASK_S11CRC()<< " , "; 
// 	    //	      
// 	    oss << " RUNHEADER_OBT=" << glA->GetRUNHEADER_OBT()<< " , "
// 		<< " RUNHEADER_PKT=" << glA->GetRUNHEADER_PKT();
// 	    oss << " WHERE ID=" << glrun->GetID() << ";";
// 	    if ( IsDebug() ) printf(" update with correct infos2: %s\n",oss.str().c_str());
// 	    conn->Query(oss.str().c_str());	
// 	  };
// 	  //
// 	  // update runheader ROOT_ID_FRAG
// 	  //
// 	  oss.str("");
// 	  oss << "UPDATE GL_RUN SET ID_RUN_FRAG = " << glrun->GetID() << " where ID = " << IDRL2A << ";";
// 	  if ( IsDebug() ) printf(" update gl_run to have cross indexing: %s\n",oss.str().c_str());
// 	  conn->Query(oss.str().c_str());
// 	  //
// 	  // now let's look for runtrailer if any in the last run
// 	  //
// 	  glA->Query_GL_RUN(IDRL2B,conn);
// 	  //
// 	  if ( glA->GetPKT_READY_COUNTER() != 0 ){
// 	    //
// 	    // the first piece contains a good runtrailer we can update all the other runs with correct infos!
// 	    //
// 	    oss.str("");
// 	    oss << "UPDATE GL_RUN_FRAGMENTS SET "
// 		<< " RUNTRAILER_TIME=" << glA->GetRUNTRAILER_TIME()<< " , "
// 		<< " RUNTRAILER_OBT=" << glA->GetRUNTRAILER_OBT()<< " , "
// 		<< " RUNTRAILER_PKT=" << glA->GetRUNTRAILER_PKT()<< " , "
// 		<< " PKT_COUNTER=" << glA->GetPKT_COUNTER()<< " , ";
// 	    //
// 	    if ( glA->GetPHYSENDRUN_MASK_S3S2S12() ){
// 	      oss << " PHYSENDRUN_MASK_S3S2S12=" << glA->GetPHYSENDRUN_MASK_S3S2S12()<< " , "; };
// 	    if ( glA->GetPHYSENDRUN_MASK_S11CRC() ) {
// 	      oss << " PHYSENDRUN_MASK_S11CRC=" << glA->GetPHYSENDRUN_MASK_S11CRC()<< " , "; };
// 	    //	      
// 	    oss << " PKT_READY_COUNTER=" << glA->GetPKT_READY_COUNTER()
// 		<< " WHERE ID=" << glrun->GetID() << ";";
// 	    if ( IsDebug() ) printf(" update with correct trailer infos: %s\n",oss.str().c_str());
// 	    conn->Query(oss.str().c_str());	
// 	    //
// 	  } else {
// 	    //
// 	    // sig no runtrailer, let set anyway what is possible...
// 	    //
// 	    oss.str("");
// 	    oss << "UPDATE GL_RUN_FRAGMENTS SET "
// 		<< " RUNTRAILER_TIME=" << glA->GetRUNTRAILER_TIME()<< " , "
// 		<< " RUNTRAILER_OBT=" << glA->GetRUNTRAILER_OBT()<< " , ";
// 	      //
// 	    if ( glA->GetPHYSENDRUN_MASK_S3S2S12() ){
// 	      oss << " PHYSENDRUN_MASK_S3S2S12=" << glA->GetPHYSENDRUN_MASK_S3S2S12()<< " , "; };
// 	    if ( glA->GetPHYSENDRUN_MASK_S11CRC() ){
// 	      oss << " PHYSENDRUN_MASK_S11CRC=" << glA->GetPHYSENDRUN_MASK_S11CRC()<< " , "; };
// 	    //	      
// 	    oss << " RUNTRAILER_PKT=" << glrun->GetRUNTRAILER_PKT()
// 		<< " WHERE ID=" << glrun->GetID() << ";";
// 	    if ( IsDebug() ) printf(" update with correct trailer infos2: %s\n",oss.str().c_str());
// 	    conn->Query(oss.str().c_str());	
// 	  };
// 	  //
// 	  UInt_t myi = glrun->GetID();
// 	  oss.str("");
// 	  oss << " ID= "<< myi;
// 	  //
// 	  glrun->Query_GL_RUN_FRAGMENTS(oss.str().c_str(),conn);   
// 	  //
// 	  // fill the new run in GL_RUN
// 	  //
// 	  glrun->SetID_RUN_FRAG(IDRL2B);
// 	  glrun->Fill_GL_RUN(conn);	
// 	  glrun->DeleteRun(conn,0,"GL_RUN_FRAGMENTS");
// 	  delete glA;
// 	  //
// 	} else {
	  //
	  // is just a repetition
	  //
	  if ( IsDebug() ) printf(" The run is already present in the GL_RUN table \n");	
	  if ( PEDANTIC ) throw -70;
	};
	//
      } else {
	if ( NoFrag() ){
	  glrun->SetID_RUN_FRAG(glrun->GetID());
	  glrun->Fill_GL_RUN(conn);	
	  glrun->DeleteRun(conn,0,"GL_RUN_FRAGMENTS");
	};     
      };
    };
  }; // EEE
  //
  return;
};


/**
 * Handle run without header or trailer
 **/
void PamelaDBOperations::HandleMissingHoT(Bool_t mishead, Bool_t mistrail, UInt_t firstev, UInt_t lastev){  
  //
  //
  // is the piece of run good (no other packets inside)?
  //
  if ( !this->IsRunConsistent(mishead,mistrail,firstev,lastev)){
    // 
    // if not, handle other pieces and continue with the first one
    //
    if ( IsDebug() ) printf("The run is not consistent, it contains non-physics packets! The run has been handled \n");
    //
  } else {
    //
    this->FillClass(mishead,mistrail,firstev,lastev);
    //
    if ( !IsRunAlreadyInserted() ){
      glrun->SetID(this->AssignRunID());
      glrun->SetID_RUN_FRAG(0);
      glrun->Fill_GL_RUN(conn);    // it'ok we arrive here only inside a file hence in the middle of the runs...
      };
    //
  };
  //
  return;
};

/**
 * 
 * check if we have non-physics packets inside the run
 * 
 */
Bool_t PamelaDBOperations::IsRunConsistent(Bool_t mishead, Bool_t mistrail, UInt_t &firstev, UInt_t &lastev){
  //  
  EventCounter *code=0;
  //
  //  UInt_t nevent = 0;
  UInt_t checkfirst = 0;
  UInt_t checklast = 0;
  UInt_t firstentry = 0;
  UInt_t lastentry = 0;
  UInt_t firstTime = 0;
  UInt_t lastTime = 0;
  UInt_t firstPkt = 0;
  UInt_t lastPkt = 0;
  UInt_t firstObt = 0;
  UInt_t lastObt = 0;
  //
  pcksList packetsNames;
  pcksList::iterator Iter;
  getPacketsNames(packetsNames);
  //
  TTree *T= 0;
  T =(TTree*)file->Get("Physics");
  if ( !T || T->IsZombie() ) throw -16;
  EventHeader *eh = 0;
  PscuHeader *ph = 0;
  T->SetBranchAddress("Header", &eh);
  //  nevent = T->GetEntries();
  //
  //
  if ( firstev == lastev+1 || lastev == firstev ) { // no events inside the run!
    //if ( firstev <= lastev+1 ) { // no events inside the run!
    if ( IsDebug() ) printf(" Checking but no events in the run! \n");
    firstev = lastev+1; // this is necessary for files with no Physics entries, should have no influence on other files
    // return true is correct
    return(true);
    //
  } else {
    //
    T->GetEntry(firstev);
    code = eh->GetCounter();
    checkfirst = 0;
    for(Iter = packetsNames.begin(); Iter != packetsNames.end(); Iter++){
      if ( strcmp(*Iter,"Physics") ) checkfirst += code->Get(GetPacketType(*Iter));
    };
    if ( IsDebug() ) printf(" Check first is %i firstev is %i\n",checkfirst,firstev);
    //
    T->GetEntry(lastev);
    code = eh->GetCounter();
    checklast = 0;
    for(Iter = packetsNames.begin(); Iter != packetsNames.end(); Iter++){
      if ( strcmp(*Iter,"Physics") ) checklast += code->Get(GetPacketType(*Iter));
    };
    if ( IsDebug() ) printf(" Check last is %i lastev is %i\n",checklast,lastev);
    //
    if ( checkfirst == checklast ){ 
      //
      if ( IsDebug() ) printf(" No packets but physics inside the run, I will consider it as good\n");
      //
      return(true);
      //
    } else {
      //
      if ( IsDebug() ) printf(" There are no-physics packets inside the run!\n");
      //
      // HERE WE MUST HANDLE THAT RUNS AND GO BACK
      //
      //      if ( IsDebug() ) printf(" Never seen this case, try to handle it anyway, it was throw -95\n");
      //
      Bool_t emptyruns = false;
      UInt_t check = 0;
      UInt_t lastevtemp = lastev;
      UInt_t firstevno = firstev;
      UInt_t rhchko=0;
      UInt_t rhchk=0;
      //
      for (UInt_t i=firstev; i<=lastev; i++){
	//
	T->GetEntry(i);
	code = eh->GetCounter();
	//
	check = 0;
	//

	// if we have a runheader set lastev then exit
	//
	for(Iter = packetsNames.begin(); Iter != packetsNames.end(); Iter++){
	  if ( strcmp(*Iter,"Physics") ) check += code->Get(GetPacketType(*Iter));
	};
	// check here if we have a runheader
	rhchko = rhchk;	  
	rhchk = code->Get(GetPacketType("RunHeader"));	  
	//
	if ( checkfirst < check || i == lastev ){
	  //
	  firstentry = firstevno;
	  //
	  if ( checkfirst < check ){
	    lastentry = i-1;
	  } else {
	    lastentry = i;
	  };
	  //
	  if ( IsDebug() ) printf(" Run between %i and %i entries\n",firstentry,lastentry);
	  //
	  glrun->SetEV_FROM(firstentry);
	  glrun->SetEV_TO(lastentry);
	  if ( lastentry == (firstentry-1) ){ // no physics packets inside physics run with no runheader no runtrailer
	    if ( IsDebug() ) printf(" no physics packets inside physics run with no runheader no runtrailer\n");
	    lastentry--;
	  };
	  glrun->SetNEVENTS(lastentry-firstentry+1);
	  //
	  glrun->Set_GL_RUNH0();
	  glrun->Set_GL_RUNT0();
	  //
	  glrun->SetLAST_TIMESYNC(0);
	  glrun->SetOBT_TIMESYNC(0);
	  //
	  T->GetEntry(firstentry);
	  ph = eh->GetPscuHeader();	  	
	  firstObt = ph->GetOrbitalTime();
	  firstTime = this->GetAbsTime(firstObt);
	  firstPkt = ph->GetCounter();	  	 
	  //
	  T->GetEntry(lastentry);
	  ph = eh->GetPscuHeader();	
	  lastObt = ph->GetOrbitalTime();
	  lastTime = this->GetAbsTime(lastObt);
	  lastPkt = ph->GetCounter();	  	 
	  //
	  glrun->SetRUNHEADER_PKT(firstPkt);
	  glrun->SetRUNTRAILER_PKT(lastPkt);
	  //
	  glrun->SetRUNHEADER_OBT(firstObt);
	  glrun->SetRUNTRAILER_OBT(lastObt);
	  //
	  if ( IsDebug() ) printf(" A THIS RUN: RUNHEADER_OBT %u RUNTRAILER_OBT %u RUNHEADER_PKT %u RUNTRAILER_PKT %u \n", glrun->GetRUNHEADER_OBT(),glrun->GetRUNTRAILER_OBT(),glrun->GetRUNHEADER_PKT(),glrun->GetRUNTRAILER_PKT());
	  if ( firstev == firstentry && !emptyruns && !mishead ){
	    glrun->Set_GL_RUNH(runh,phh);
	    firstTime = this->GetAbsTime(phh->GetOrbitalTime());
	    if ( IsDebug() ) printf(" We have the runheader \n");
	  };
	  if ( lastev == i && !mistrail ){
	    glrun->Set_GL_RUNT(runt,pht);
	    lastTime = this->GetAbsTime(pht->GetOrbitalTime());
	    if ( IsDebug() ) printf(" We have the runtrailer \n");
	  };
	  //
	  if ( IsDebug() ) printf(" B THIS RUN: RUNHEADER_OBT %u RUNTRAILER_OBT %u RUNHEADER_PKT %u RUNTRAILER_PKT %u \n", glrun->GetRUNHEADER_OBT(),glrun->GetRUNTRAILER_OBT(),glrun->GetRUNHEADER_PKT(),glrun->GetRUNTRAILER_PKT());
	  if ( lastentry == (firstentry-2) ){ // no events in the run
	    emptyruns = true;
	    if ( IsDebug() ) printf(" No events in the run \n");
	    lastTime = firstTime;
	    if ( (UInt_t)firstTime == this->GetAbsTime(phh->GetOrbitalTime()) ){
	      lastObt = glrun->RUNHEADER_OBT;
	      lastPkt = glrun->RUNHEADER_PKT;
	    } else {
	      lastObt = firstObt;
	      lastPkt = firstPkt;
	    };
	    glrun->SetRUNTRAILER_PKT(lastPkt);
	    glrun->SetRUNTRAILER_OBT(lastObt);
	    lastentry++;
	  };
	  //	  
	  this->SetCommonGLRUN(firstTime,lastTime);
	  this->SetPhysEndRunVariables();
	  //
	  if ( chminentry == firstentry  ){ // EEE
            if ( IsDebug() ) printf(" Inside isrunconsistent found a fragment of run at the beginning of the file, put it in the fragment table \n");
	    //
	    //	    this->HandleRunFragments(true,mistrail,firstentry,lastentry); // cannot call it here since it enters a loop which will destroy the already stored variables if we arrive here from HandleRunFragments
	    //

	    mishead = true;


	    UInt_t rhfirstev = firstentry;
	    //  UInt_t rtlastev = lastentry;
	    Bool_t found = false;
	    Bool_t foundinrun = false;
	    //
	    TSQLResult *result = 0;
	    TSQLRow    *row    = 0;
	    //
	    stringstream oss;
	    oss.str("");
	    //
	    // we have now the good first piece of a run, fill the glrun object
	    //
	    //  if ( rhfirstev != firstev && !mishead ) mishead = true;
	    //  if ( rtlastev != lastev && !mistrail ) mistrail = true;
	    //
	    //  this->FillClass(mishead,mistrail,firstev,lastev);
	    //
	    if ( IsDebug() ) printf("zz The run is good, is it the other piece in the GL_RUN_FRAGMENTS table?\n");
	    if ( IsDebug() ) printf("zz C THIS RUN: RUNHEADER_OBT %u RUNTRAILER_OBT %u RUNHEADER_PKT %u RUNTRAILER_PKT %u \n", glrun->GetRUNHEADER_OBT(),glrun->GetRUNTRAILER_OBT(),glrun->GetRUNHEADER_PKT(),glrun->GetRUNTRAILER_PKT());
	    //
	    // First of all insert the run in the fragment table...
	    //
	    oss.str("");
	    oss << " SELECT ID FROM GL_RUN_FRAGMENTS WHERE "
		<< " BOOT_NUMBER=" << this->GetBOOTnumber() << " AND ("
		<< " (RUNHEADER_TIME>=" << (UInt_t)(glrun->GetRUNHEADER_TIME()-10) << " AND "
		<< " RUNTRAILER_TIME<=" << (UInt_t)(glrun->GetRUNTRAILER_TIME()+10) << " AND ("
		<< " RUNHEADER_OBT>=" << glrun->GetRUNHEADER_OBT() << " OR "
		<< " RUNHEADER_PKT>=" << glrun->GetRUNHEADER_PKT() << ") AND ("
		<< " RUNTRAILER_OBT<=" << glrun->GetRUNTRAILER_OBT() << " OR "
		<< " RUNTRAILER_PKT<=" << glrun->GetRUNTRAILER_PKT() << ") ) OR "
		<< " (RUNHEADER_TIME<=" << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "
		<< " RUNTRAILER_TIME>=" << (UInt_t)glrun->GetRUNTRAILER_TIME() <<" AND ("
		<< " RUNHEADER_OBT<=" << glrun->GetRUNHEADER_OBT() << " OR "
		<< " RUNHEADER_PKT<=" << glrun->GetRUNHEADER_PKT() << ") AND ("
		<< " RUNTRAILER_OBT>=" << glrun->GetRUNTRAILER_OBT() << " OR "
		<< " RUNTRAILER_PKT>=" << glrun->GetRUNTRAILER_PKT() << ") ));";
	    //
	    if ( IsDebug() ) printf(" check if run has been inserted: query is \n %s \n",oss.str().c_str());
	    result = conn->Query(oss.str().c_str());
	    //
	    if ( !result ) throw -4;
	    //
	    row = result->Next();
	    //
	    if ( !row ){
	      //
	      // no, insert this run in the GL_RUN_FRAGMENTS table (check if exist before!)
	      //
	      if ( IsDebug() ) printf(" The run is new \n");
	      if ( IsDebug() ) printf(" -> fill the GL_RUNFRAGMENTS table \n");
	      //
	      glrun->SetID(this->AssignRunID());
	      glrun->SetID_RUN_FRAG(0);
	      glrun->Fill_GL_RUN_FRAGMENTS(conn);
	      //
	    } else {
	      if ( IsDebug() ) printf(" The run is already present in the fragment table \n");
	      if ( PEDANTIC ) throw -69;
	      //    return;
	    };
	    //
	    if ( chewbacca && mishead && mistrail ) goto zjustcheck;
	    //
	    // can we find the other piece of the run in the GL_RUN_FRAGMENTS table?
	    //
	    if ( mishead && ( rhfirstev == firstev || chewbacca ) ) { // look for runheader (only when at the beginning of the file, if at the end and the runh is
	      // missing it no way we can found a piece in the frag table
	      //
	      oss.str("");
	      oss << " SELECT ID,TRK_CALIB_USED,RUNTRAILER_TIME,RUNTRAILER_OBT,RUNHEADER_PKT,RUNTRAILER_PKT FROM GL_RUN_FRAGMENTS WHERE "
		  << " BOOT_NUMBER=" << this->GetBOOTnumber() << " AND "
		  << " RUNHEADER_TIME <= " << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "
		  << " ID != " << glrun->ID
		  << " ORDER BY RUNHEADER_TIME DESC LIMIT 1;"; // DESC NOT ASC!!
	      //
	      if ( IsDebug() ) printf(" look for runheader in the fragments table: query is \n %s \n",oss.str().c_str());
	      result = conn->Query(oss.str().c_str());
	      //
	      if ( !result ) throw -4;
	      //
	      row = result->Next();
	      //
	      if ( !row && NoFrag() ){
		//
		oss.str("");
		oss << " SELECT ID,TRK_CALIB_USED,RUNTRAILER_TIME,RUNTRAILER_OBT,RUNHEADER_PKT,RUNTRAILER_PKT FROM GL_RUN WHERE "
		    << " BOOT_NUMBER=" << this->GetBOOTnumber() << " AND "
		    << " RUNHEADER_TIME <= " << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "
		    << " ID != " << glrun->ID
		    << " AND ID=ID_RUN_FRAG ORDER BY RUNHEADER_TIME DESC LIMIT 1;"; // DESC NOT ASC!!
		//
		if ( IsDebug() ) printf(" look for runheader in the GL_RUN table: query is \n %s \n",oss.str().c_str());
		result = conn->Query(oss.str().c_str());
		//
		if ( !result ) throw -4;
		//
		foundinrun = true;
		//
		row = result->Next();
		//
	      };
	      //
	      if ( !row ){
		if ( IsDebug() ) printf(" the corresponding piece has NOT been found \n");
		found = false;
	      } else {
		//
		found = false; // default value
		//
		if ( IsDebug() ) printf(" C Found a possible candidate, checking if it is the good one... \n");
		//
		// if we have both runheader and runtrailer we can check with pkt_counter:
		//
		if ( !mistrail && (UInt_t)atoll(row->GetField(1)) != 0 ){
		  ULong64_t chkpkt = 0;
		  ULong64_t pktt = (ULong64_t)PKT(glrun->GetRUNTRAILER_PKT());
		  ULong64_t pkth = (ULong64_t)PKT((UInt_t)atoll(row->GetField(4)));
		  //
		  chkpkt = pkth + (ULong64_t)glrun->GetPKT_COUNTER() + 1ULL + 1ULL;
		  //
		  if ( labs(chkpkt-pktt)<2 ){
		    //
		    if ( IsDebug() ) printf(" FOUND!!! check %llu pktt %llu \n",chkpkt,pktt);
		    //
		    found = true;
		    //
		  } else {
		    //
		    if ( IsDebug() ) printf(" The check with pkt counter failed: check %llu pktt %llu \n",chkpkt,pktt);
		    //
		    found = false;
		    //
		  };
		};
		if ( !found && chewbacca ) goto zjustcheck;
		if ( !found ){
		  //
		  // if we arrive here we were not able to decide if the two pieces matches using only the pkt counter information, we must check times and obts
		  //
		  ULong64_t chkpkt1 = 0;
		  ULong64_t orunh1 = (ULong64_t)PKT(glrun->GetRUNHEADER_PKT());
		  ULong64_t dbrunt1 = (ULong64_t)PKT((UInt_t)atoll(row->GetField(5)));
		  chkpkt1 = labs(orunh1-dbrunt1);
		  //
		  ULong64_t chkpkt2 = 0;
		  ULong64_t orunh2 = (ULong64_t)OBT(glrun->GetRUNHEADER_OBT());
		  ULong64_t dbrunt2 = (ULong64_t)OBT((UInt_t)atoll(row->GetField(3)));
		  chkpkt2 = labs(orunh2-dbrunt2);
		  //
		  ULong64_t chkpkt3 = 0;
		  ULong64_t orunh3 = (ULong64_t)(glrun->GetRUNHEADER_TIME());
		  ULong64_t dbrunt3 = (ULong64_t)((UInt_t)atoll(row->GetField(2)));
		  chkpkt3 = labs(orunh3-dbrunt3);
		  //
		  if ( (chkpkt1 < 200 || chkpkt2 < 20000) && chkpkt3 < 20 ){
		    //    if ( chkpkt1 < 100 && chkpkt2 < 30000 && chkpkt3 < 30 ){
		    //
		    if ( IsDebug() ) printf(" FOUND!!! check1 %llu<200 cechk2 %llu<20000 check3 %llu<20 \n",chkpkt1,chkpkt2,chkpkt3);
		    //
		    found = true;
		    //
		  } else {
		    //
		    if ( IsDebug() ) printf(" Check failed: check1 %llu<200? cechk2 %llu<20000? check3 %llu<20? \n",chkpkt1,chkpkt2,chkpkt3);
		    //
		    found = false;
		    //
		  };
		};
	      };
	      //
	      if ( found ){
		//
		// we have found the missing piece, glue the two together, merge the informations, fill the gl_run table (check first runs do not exists), delete entry in frag table
		//
		if ( IsDebug() ) printf(" now you can handle the piece of the run \n ");
		//
		if ( foundinrun ){
		  glrun->RestoreRun(conn,(UInt_t)atoll(row->GetField(0)),"GL_RUN_FRAGMENTS");
		  glrun->DeleteRun(conn,(UInt_t)atoll(row->GetField(0)),"GL_RUN");
		};
		//
		GL_RUN *glrun1 = new GL_RUN();
		//
		//      UInt_t idfrag = (UInt_t)atoll(row->GetField(0));
		//
		oss.str("");
		oss << " ID="<<row->GetField(0)<<";";
		//
		glrun1->Query_GL_RUN_FRAGMENTS(oss.str().c_str(),conn); // here we have runheader infos
		//
		// merge infos
		//
		UInt_t apkt = PKT(glrun1->GetRUNTRAILER_PKT());
		ULong64_t aobt = OBT(glrun1->GetRUNTRAILER_OBT());
		UInt_t bpkt = PKT(glrun->GetRUNHEADER_PKT());
		ULong64_t bobt = OBT(glrun->GetRUNHEADER_OBT());
		if ( IsDebug() ) printf(" Check overlapping events: %u %u %llu %llu firstev is %i\n",apkt,bpkt,aobt,bobt,firstev);
		TTree *T= 0;
		T = (TTree*)file->Get("Physics");
		if ( !T || T->IsZombie() ) throw -16;
		EventHeader *eh = 0;
		PscuHeader *ph = 0;
		T->SetBranchAddress("Header", &eh);
		while ( apkt > bpkt && aobt > bobt && firstev < lastev ){
		  T->GetEntry(firstev);
		  ph = eh->GetPscuHeader();
		  bpkt = PKT(ph->GetCounter());
		  bobt = OBT(ph->GetOrbitalTime());
		  firstev++;
		  if ( PEDANTIC ) throw -71;
		};
		if ( IsDebug() ) printf(" Check overlapping events done: %u %u %llu %llu firstev is %i\n",apkt,bpkt,aobt,bobt,firstev);
		//
		glrun1->SetPKT_COUNTER(glrun->GetPKT_COUNTER());
		glrun1->SetPKT_READY_COUNTER(glrun->GetPKT_READY_COUNTER());
		glrun1->SetRUNTRAILER_TIME(glrun->GetRUNTRAILER_TIME());
		glrun1->SetRUNTRAILER_OBT(glrun->GetRUNTRAILER_OBT());
		glrun1->SetRUNTRAILER_PKT(glrun->GetRUNTRAILER_PKT());
		//
		glrun->SetEV_FROM(firstev);
    	        glrun->SetEV_TO(lastev); // 10 RED ghost run bug
		glrun->SetNEVENTS(lastev-firstev+1);
		//
		glrun->SetRUNHEADER_TIME(glrun1->GetRUNHEADER_TIME());
		glrun->SetRUNHEADER_OBT(glrun1->GetRUNHEADER_OBT());
		glrun->SetRUNHEADER_PKT(glrun1->GetRUNHEADER_PKT());
		glrun->SetCOMPILATIONTIMESTAMP(glrun1->GetCOMPILATIONTIMESTAMP());
		glrun->SetFAV_WRK_SCHEDULE(glrun1->GetFAV_WRK_SCHEDULE());
		glrun->SetEFF_WRK_SCHEDULE(glrun1->GetEFF_WRK_SCHEDULE());
		glrun->SetPRH_VAR_TRG_MODE_A(glrun1->GetPRH_VAR_TRG_MODE_A());
		glrun->SetPRH_VAR_TRG_MODE_B(glrun1->GetPRH_VAR_TRG_MODE_B());
		glrun->SetACQ_BUILD_INFO(glrun1->GetACQ_BUILD_INFO());
		glrun->SetACQ_VAR_INFO(glrun1->GetACQ_VAR_INFO());
		glrun->SetRM_ACQ_AFTER_CALIB(glrun1->GetRM_ACQ_AFTER_CALIB());
		glrun->SetRM_ACQ_SETTING_MODE(glrun1->GetRM_ACQ_SETTING_MODE());
		glrun->SetTRK_CALIB_USED(glrun1->GetTRK_CALIB_USED());
		glrun->SetCAL_DSP_MASK(glrun1->GetCAL_DSP_MASK());
		glrun->SetLAST_TIMESYNC(glrun1->GetLAST_TIMESYNC());
		glrun->SetOBT_TIMESYNC(glrun1->GetOBT_TIMESYNC());
		//
		if ( glrun1->GetPHYSENDRUN_MASK_S3S2S12() ) glrun->SetPHYSENDRUN_MASK_S3S2S12(glrun1->GetPHYSENDRUN_MASK_S3S2S12());
		if ( glrun1->GetPHYSENDRUN_MASK_S11CRC() ) glrun->SetPHYSENDRUN_MASK_S11CRC(glrun1->GetPHYSENDRUN_MASK_S11CRC());
		//
		if ( !IsRunAlreadyInserted() ){
		  //
		  //      glrun->SetID(this->AssignRunID());
		  glrun->SetID_RUN_FRAG(glrun1->GetID());
		  glrun->Fill_GL_RUN(conn);
		  //
		  // set id number
		  //
		  glrun1->SetID_RUN_FRAG(glrun->GetID());
		  glrun1->Fill_GL_RUN(conn);
		  //
		};
		// delete old entry in fragment table
		//
		glrun->DeleteRun(conn,0,"GL_RUN_FRAGMENTS");
		glrun1->DeleteRun(conn,0,"GL_RUN_FRAGMENTS");
		//
		delete glrun1;
		//
		//
		//      return;
		//
	      };
	      //
	    };
	    //
	    //
	  zjustcheck:
	    //
	    if ( !found ){
	      //
	      if ( IsDebug() ) printf(" not found, check if we have already processed the file \n ");
	      //
	      // not found, has this run already inserted in the GL_RUN or in the GL_RUN_FRAGMENTS table?
	      //
	      oss.str("");
	      oss << " SELECT ID FROM GL_RUN WHERE "
		  << " BOOT_NUMBER=" << this->GetBOOTnumber() << " AND ("
		  << " (RUNHEADER_TIME>=" << (UInt_t)(glrun->GetRUNHEADER_TIME()-10) << " AND "
		  << " RUNTRAILER_TIME<=" << (UInt_t)(glrun->GetRUNTRAILER_TIME()+10) << " AND ("
		  << " RUNHEADER_OBT>=" << glrun->GetRUNHEADER_OBT() << " OR "
		  << " RUNHEADER_PKT>=" << glrun->GetRUNHEADER_PKT() << ") AND ("
		  << " RUNTRAILER_OBT<=" << glrun->GetRUNTRAILER_OBT() << " OR "
		  << " RUNTRAILER_PKT<=" << glrun->GetRUNTRAILER_PKT() << ") ) OR "
		  << " (RUNHEADER_TIME<=" << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "
		  << " RUNTRAILER_TIME>=" << (UInt_t)glrun->GetRUNTRAILER_TIME() <<" AND ("
		  << " RUNHEADER_OBT<=" << glrun->GetRUNHEADER_OBT() << " OR "
		  << " RUNHEADER_PKT<=" << glrun->GetRUNHEADER_PKT() << ") AND ("
		  << " RUNTRAILER_OBT>=" << glrun->GetRUNTRAILER_OBT() << " OR "
		  << " RUNTRAILER_PKT>=" << glrun->GetRUNTRAILER_PKT() << ") ));";
	      //
	      if ( IsDebug() ) printf(" check if run has been inserted: query is \n %s \n",oss.str().c_str());
	      result = conn->Query(oss.str().c_str());
	      //
	      if ( !result ) throw -4;
	      //
	      row = result->Next();
	      //
	      if ( row ){
		if ( IsDebug() ) printf(" The run is already present in the GL_RUN table \n");
		if ( PEDANTIC ) throw -70;
	      } else {
		if ( NoFrag() ){
		  glrun->SetID_RUN_FRAG(glrun->GetID());
		  glrun->Fill_GL_RUN(conn);
		  glrun->DeleteRun(conn,0,"GL_RUN_FRAGMENTS");
		};
	      };
	    }; // EEE


          } else {
	    if ( !IsRunAlreadyInserted() ){
	      glrun->SetID(this->AssignRunID());
	      glrun->SetID_RUN_FRAG(0);
	      glrun->Fill_GL_RUN(conn);
	    };
          }; // EEE
	  //
	  firstevno = lastentry + 1;
	  //
	  checkfirst = check;
	  //
	};
	//
	if ( i > firstev ){
	  if ( rhchko != rhchk ){
	    if ( IsDebug() ) printf("oh oh... we have a runheader! stop here and handle later the remaining piece\n");
	    lastev = i;
	    return(false);
	  };
	};
	//
	if ( check == checklast && i != lastev ){
	  lastevtemp = i - 1;
	  i = lastev - 1; 
	};
	//
      };
      //
      lastev = lastevtemp;
      //
      return(false);
      //
    };
  };
  //
  return(false); // should never arrive here
};

/**
 * 
 * we end up here when we have a runheader and a runtrailer but they seems not belonging to the same run since the number of events does not coincide with the
 * number of event written in the runtrailer. We try to split into different runs scanning the physics events from the runheader to the runtrailer and
 * looking for non-physics packets inside.
 * 
 */
void PamelaDBOperations::HandleSuspiciousRun(){
  //  
  PacketType *pctp=0;
  EventCounter *codt=0;
  EventCounter *codh=0;
  EventCounter *code=0;
  UInt_t firstev = 0;
  UInt_t lastev = 0;
  //  UInt_t nevent = 0;
  UInt_t checkfirst = 0;
  UInt_t checklast = 0;
  UInt_t firstentry = 0;
  UInt_t lastentry = 0;
  UInt_t firstTime = 0;
  UInt_t lastTime = 0;
  UInt_t firstPkt = 0;
  UInt_t lastPkt = 0;
  UInt_t firstObt = 0;
  UInt_t lastObt = 0;
  //
  pcksList packetsNames;
  pcksList::iterator Iter;
  getPacketsNames(packetsNames);
  //
  TTree *rh=0;
  rh = (TTree*)file->Get("RunHeader");
  if ( !rh || rh->IsZombie() ) throw -17;
  TTree *T=0;
  T =(TTree*)file->Get("Physics");
  if ( !T || T->IsZombie() ) throw -16;
  EventHeader *eh = 0;
  PscuHeader *ph = 0;
  T->SetBranchAddress("Header", &eh);
  //  nevent = T->GetEntries();
  //
  codt = eht->GetCounter();
  codh = ehh->GetCounter();
  firstev = codh->Get(pctp->Physics);
  lastev = codt->Get(pctp->Physics)-1;
  if ( IsDebug() ) printf(" From the current runheader firstev is %u from the runtrailer lastev is %u \n",firstev,lastev);
  //
  if ( firstev == lastev+1 ) { // no events inside the run!
    if ( IsDebug() ) printf(" Checking but no events in the run! \n");
    //
    this->FillClass();
    if ( !IsRunAlreadyInserted() ){
      glrun->SetID(this->AssignRunID());
      glrun->SetID_RUN_FRAG(0);
      glrun->Fill_GL_RUN(conn);    
    };
    //
  } else {
    //
    UInt_t nrunh  = 0 + codh->Get(pctp->RunHeader);
    UInt_t nrunh1 = 0 + codh->Get(pctp->RunHeader);
    T->GetEntry(firstev);
    code = eh->GetCounter();
    checkfirst = 0;
    for(Iter = packetsNames.begin(); Iter != packetsNames.end(); Iter++){
      if ( strcmp(*Iter,"Physics") ) checkfirst += code->Get(GetPacketType(*Iter));
      if ( !strcmp(*Iter,"RunHeader") ) nrunh1++;
    };
    if ( IsDebug() ) printf(" Check first is %i \n",checkfirst);
    //
    T->GetEntry(lastev);
    code = eh->GetCounter();
    checklast = 0;
    for(Iter = packetsNames.begin(); Iter != packetsNames.end(); Iter++){
      if ( strcmp(*Iter,"Physics") ) checklast += code->Get(GetPacketType(*Iter));
    };
    if ( IsDebug() ) printf(" Check last is %i \n",checklast);
    //
    if ( checkfirst == checklast ){ 
      //
      if ( IsDebug() ) printf(" No packets but physics inside the run, I will consider it as good\n");
      //
      this->FillClass();
      if ( !IsRunAlreadyInserted() ){
	glrun->SetID(this->AssignRunID());
	glrun->SetID_RUN_FRAG(0);
	glrun->Fill_GL_RUN(conn);         
      };
      //
    } else {
      //
      if ( IsDebug() ) printf(" There are no-physics packets inside the run, try to separate runs \n");
      //
      Bool_t emptyruns = false;
      UInt_t check = 0;
      UInt_t firstevno = firstev;
      //
      for (UInt_t i=firstev; i<=lastev; i++){
	//
	T->GetEntry(i);
	code = eh->GetCounter();
	//
	check = 0;
	//
	for(Iter = packetsNames.begin(); Iter != packetsNames.end(); Iter++){
	  if ( strcmp(*Iter,"Physics") ) check += code->Get(GetPacketType(*Iter));
	  if ( !strcmp(*Iter,"RunHeader") ) nrunh++;
	};
	//
	if ( checkfirst < check || i == lastev ){
	  //
	  firstentry = firstevno;
	  //
	  if ( checkfirst < check ){
	    lastentry = i-1;
	  } else {
	    lastentry = i;
	  };
	  //
	  if ( IsDebug() ) printf(" Run between %i and %i entries\n",firstentry,lastentry);
	  //
	  glrun->SetEV_FROM(firstentry);
	  glrun->SetEV_TO(lastentry);
	  if ( lastentry == (firstentry-1) ){ // no physics packets inside physics run with no runheader no runtrailer
	    if ( IsDebug() ) printf(" no physics packets inside physics run with no runheader no runtrailer\n");
	    lastentry--;
	  };
	  glrun->SetNEVENTS(lastentry-firstentry+1);
	  //
	  glrun->Set_GL_RUNH0();
	  glrun->Set_GL_RUNT0();
	  //
	  glrun->SetLAST_TIMESYNC(0);
	  glrun->SetOBT_TIMESYNC(0);
	  //
	  T->GetEntry(firstentry);
	  ph = eh->GetPscuHeader();	  	
	  firstObt = ph->GetOrbitalTime();
	  firstTime = this->GetAbsTime(firstObt);
	  firstPkt = ph->GetCounter();	  	 
	  //
	  T->GetEntry(lastentry);
	  ph = eh->GetPscuHeader();	
	  lastObt = ph->GetOrbitalTime();
	  lastTime = this->GetAbsTime(lastObt);
	  lastPkt = ph->GetCounter();	  	 
	  //
	  glrun->SetRUNHEADER_PKT(firstPkt);
	  glrun->SetRUNTRAILER_PKT(lastPkt);
	  //
	  glrun->SetRUNHEADER_OBT(firstObt);
	  glrun->SetRUNTRAILER_OBT(lastObt);
	  //
	  if ( IsDebug() ) printf(" AA THIS RUN: RUNHEADER_OBT %u RUNTRAILER_OBT %u RUNHEADER_PKT %u RUNTRAILER_PKT %u \n", glrun->GetRUNHEADER_OBT(),glrun->GetRUNTRAILER_OBT(),glrun->GetRUNHEADER_PKT(),glrun->GetRUNTRAILER_PKT());
	  //
	  if ( (firstev == firstentry && !emptyruns) || nrunh == (nrunh1 + 1) ){
	    rh->GetEntry(nrunh1-1);
	    phh = ehh->GetPscuHeader();
	    nrunh1++;
	    glrun->Set_GL_RUNH(runh,phh);
	    firstTime = this->GetAbsTime(phh->GetOrbitalTime());
	    if ( IsDebug() ) printf(" We have the runheader \n");
	  };
	  if ( lastev == i && checkfirst == check ){
	    glrun->Set_GL_RUNT(runt,pht);
	    lastTime = this->GetAbsTime(pht->GetOrbitalTime());
	    if ( IsDebug() ) printf(" We have the runtrailer \n");
	  };
	  if ( IsDebug() ) printf(" BB THIS RUN: RUNHEADER_OBT %u RUNTRAILER_OBT %u RUNHEADER_PKT %u RUNTRAILER_PKT %u \n", glrun->GetRUNHEADER_OBT(),glrun->GetRUNTRAILER_OBT(),glrun->GetRUNHEADER_PKT(),glrun->GetRUNTRAILER_PKT());
	  //
	  if ( lastentry == (firstentry-2) ){ // no events in the run
	    emptyruns = true;
	    if ( IsDebug() ) printf(" No events in the run \n");
	    lastTime = firstTime;
	    if ( (UInt_t)firstTime == this->GetAbsTime(phh->GetOrbitalTime()) ){
	      lastObt = glrun->RUNHEADER_OBT;
	      lastPkt = glrun->RUNHEADER_PKT;
	    } else {
	      lastObt = firstObt;
	      lastPkt = firstPkt;
	    };
	    glrun->SetRUNTRAILER_PKT(lastPkt);
	    glrun->SetRUNTRAILER_OBT(lastObt);
	    lastentry++;
	  };
	  //	  
	  this->SetCommonGLRUN(firstTime,lastTime);
	  this->SetPhysEndRunVariables();
	  //
	  if ( !IsRunAlreadyInserted() ){
	    glrun->SetID(this->AssignRunID());
	    glrun->SetID_RUN_FRAG(0);
	    glrun->Fill_GL_RUN(conn);      
	  };
	  //
	  if ( i == lastev && checkfirst < check ){ // if the last event gives a wrong check...
	    //
	    firstentry = i;
	    //
	    lastentry = i;
	    //
	    if ( IsDebug() ) printf(" Run between %i and %i entries\n",firstentry,lastentry);
	    //
	    glrun->SetEV_FROM(firstentry);
	    glrun->SetEV_TO(lastentry);
	    glrun->SetNEVENTS(lastentry-firstentry+1);
	    //
	    glrun->Set_GL_RUNH0();
	    //
	    glrun->SetLAST_TIMESYNC(0);
	    glrun->SetOBT_TIMESYNC(0);
	    //
	    T->GetEntry(firstentry);
	    ph = eh->GetPscuHeader();	  	
	    firstObt = ph->GetOrbitalTime();
	    firstTime = this->GetAbsTime(firstObt);
	    firstPkt = ph->GetCounter();	  	 
	    //
	    glrun->SetRUNHEADER_PKT(firstPkt);
	    //
	    glrun->SetRUNHEADER_OBT(firstObt);
	    //
	    glrun->Set_GL_RUNT(runt,pht);
	    lastTime = this->GetAbsTime(pht->GetOrbitalTime());
	    if ( IsDebug() ) printf(" We have the runtrailer \n");
	    //	  
	    this->SetCommonGLRUN(firstTime,lastTime);
	    this->SetPhysEndRunVariables();
	    //
	    if ( !IsRunAlreadyInserted() ){
	      glrun->SetID(this->AssignRunID());
	      glrun->SetID_RUN_FRAG(0);
	      glrun->Fill_GL_RUN(conn);      
	    };
	  };
	  //
	  firstevno = lastentry + 1;
	  //
	  checkfirst = check;
	  //
	};
	//
	if ( check == checklast && i != lastev ) i = lastev - 1; // >>>>>>>>>>>>>>>>>>>>>>
	//
      };
    };
  };
  //
  return;
};


/**
 * Scan calorimeter calibrations packets, fill the GL_CALO_CALIB table
 */
Int_t PamelaDBOperations::insertCALO_CALIB(){
  //
  TSQLResult *result = 0;
  TSQLRow    *row    = 0;
  //
  stringstream oss;
  oss.str("");
  //
  CalibCalPedEvent *calibCalPed = 0;
  TTree *tr = 0;
  EventHeader *eh = 0;
  PscuHeader *ph = 0;
  //
  UInt_t nevents = 0;
  UInt_t fromtime = 0;
  UInt_t totime = 0;
  UInt_t obt = 0;
  UInt_t pkt = 0;
  Float_t totped = 0.;
  //
  tr = (TTree*)file->Get("CalibCalPed");
  if ( !tr || tr->IsZombie() ) throw -21;
  //
  tr->SetBranchAddress("CalibCalPed", &calibCalPed);
  tr->SetBranchAddress("Header", &eh);
  nevents = tr->GetEntries();
  //
  if ( !nevents ) return(1);
  //
  for (UInt_t i=0; i < nevents; i++){
    tr->GetEntry(i);
    for (UInt_t section = 0; section < 4; section++){
      //
      if ( calibCalPed->cstwerr[section] ){
	valid = 1;
	if ( calibCalPed->cperror[section] ) valid = 0;
	//
	// check pedestal values for one plane, if all zeros calibration is not valid (calorimeter power problems) [8th data reduction bug, fixed on 25/11/2009 by E.M.]
	//
	totped = 0.;
	Int_t ns = 0;
	if ( section == 2 ) ns = 3; 
	if ( section == 3 ) ns = 1; 
	if ( section == 1 ) ns = 2; 
	for (UInt_t ss=0; ss<96; ss++){
	  totped += fabs(calibCalPed->calped[ns][0][ss]);
	}
	if ( totped < 1. ){
	  if ( IsDebug() ) printf(" Section %i totped %f -  No calibration data! Calorimeter power problems? \n",section,totped);
	  valid = 0;
	};
	//
	ph = eh->GetPscuHeader();
	obt = ph->GetOrbitalTime();  
	pkt = ph->GetCounter();  
	fromtime = this->GetAbsTime(ph->GetOrbitalTime());  
	if ( this->PKT(pkt) >= this->PKT(pktfirst) && this->PKT(pkt) <= upperpkt && this->OBT(obt) >= this->OBT(obtfirst) && this->OBT(obt) <= upperobt ){
	  //
	  if ( IsDebug() ) printf(" Calo calibration for section %i at time %u obt %u pkt %u \n",section,fromtime,obt,pkt);
	  //
	  // check if the calibration has already been inserted
	  //
	  oss.str("");
	  oss << " SELECT ID FROM GL_CALO_CALIB WHERE "
	      << " SECTION = "<< section << " AND "
	      << " BOOT_NUMBER = "<< this->GetBOOTnumber() << " AND "
	      << " OBT = "<< obt << " AND "
	      << " PKT = "<< pkt << ";";
	  //
	  if ( IsDebug() ) printf(" Check if the calo calibration has already been inserted: query is \n %s \n",oss.str().c_str());
	  result = conn->Query(oss.str().c_str());
	  //
	  if ( !result ) throw -4;
	  //
	  row = result->Next();
	  //
	  if ( row ){
	    //
	    if ( IsDebug() ) printf(" Calo calibration already inserted in the DB\n");
	    if ( PEDANTIC ) throw -73;
	    //
	  } else {
	    //
	    // we have to insert a new calibration, check where to place it
	    //
	    oss.str("");
	    oss << " SELECT ID,TO_TIME FROM GL_CALO_CALIB WHERE "
		<< " SECTION = "<< section << " AND "
		<< " FROM_TIME < "<< fromtime << " AND "
		<< " TO_TIME > "<< fromtime << ";";
	    //
	    if ( IsDebug() ) printf(" Check where to place the  calo calibration: query is \n %s \n",oss.str().c_str());
	    result = conn->Query(oss.str().c_str());
	    //
	    if ( !result ) throw -4;
	    //
	    row = result->Next();
	    //
	    if ( !row ){
	      //
	      // no calibrations in the db contain our calibration
	      //
	      if ( IsDebug() ) printf(" Calibration with fromtime lower than others to be inserted in the DB for section %i \n",section);
	      if ( fromtime < 1150871000 ){ //1150866904
		if ( IsDebug() ) printf(" First PAMELA flight calibration at time %u \n",fromtime);
		fromtime = 0;// the first flight calibration was taken at about  1156429100 s, this line allow to analyze first runs in raw mode
	      };
	      //
	      oss.str("");
	      oss << " SELECT FROM_TIME FROM GL_CALO_CALIB WHERE "
		  << " SECTION = "<< section << " AND "
		  << " FROM_TIME > "<< fromtime << " ORDER BY FROM_TIME ASC LIMIT 1;";
	      //
	      if ( IsDebug() ) printf(" Check the upper limit for calibration: query is \n %s \n",oss.str().c_str());
	      result = conn->Query(oss.str().c_str());
	      //
	      if ( !result ) throw -4;
	      //
	      row = result->Next();
	      if ( !row ){
		totime = numeric_limits<UInt_t>::max();
	      } else {
		totime = (UInt_t)atoll(row->GetField(0));
	      };
	      //
	    } else {
	      //
	      // determine upper and lower limits and make space for the new calibration
	      //
	      totime = (UInt_t)atoll(row->GetField(1));
	      //
	      oss.str("");
	      oss << " UPDATE GL_CALO_CALIB SET "   
		  << " TO_TIME = "<< fromtime << " WHERE "  // NOTICE: to_time is equal to from_time of the calibration before, so the interval is: [from_time,to_time[
		  << " ID = "<< row->GetField(0) << ";";
	      //
	      if ( IsDebug() ) printf(" Make space for the new calibration: query is \n %s \n",oss.str().c_str());
	      result = conn->Query(oss.str().c_str());
	      //
	      if ( !result ) throw -4;
	      //
	    };
	    //
	    oss.str("");
	    oss << " INSERT INTO GL_CALO_CALIB (ID,ID_ROOT_L0,EV_ROOT,FROM_TIME,TO_TIME,SECTION,OBT,PKT,BOOT_NUMBER,VALIDATION) "
		<< " VALUES (NULL,' "
		<< idroot << "','"
		<< i << "','"
		<< fromtime << "','"
		<< totime << "','"
		<< section << "','"
		<< obt << "','"
		<< pkt << "','"
		<< this->GetBOOTnumber() << "','"
		<< valid << "');";
	    //
	    if ( IsDebug() ) printf(" Insert the new calibration: query is \n %s \n",oss.str().c_str());
	    //
	    result = conn->Query(oss.str().c_str());
	    //
	    if ( !result ) throw -4;
	    //
	  };
	  //
	} else {
	  //
	  if ( IsDebug() ) printf(" Calo calibration for section %i at time %u obt %u pkt %u OUTSIDE the considered interval \n",section,fromtime,obt,pkt);
	  //	  if ( PEDANTIC ) throw -74;
	  //
	};      
	//      
      };
    };
  };
  //
  return(0);
};
 

/**
 * Scan calorimeter calibrations packets, fill the GL_CALO_CALIB table
 */
Int_t PamelaDBOperations::insertCALOPULSE_CALIB(){
  //
  TSQLResult *result = 0;
  TSQLRow    *row    = 0;
  //
  stringstream oss;
  oss.str("");
  //
  oss << " DESCRIBE GL_CALOPULSE_CALIB;";
  if ( IsDebug() ) printf(" Check if the GL_CALOPULSE_CALIB table exists: query is \n %s \n",oss.str().c_str());
  result = conn->Query(oss.str().c_str());
  //
  if ( conn->GetErrorCode() ){
    if ( IsDebug() ) printf(" The GL_CALOPULSE_CALIB table does not exists! \n");
    throw -30;
  };
  //
  // CaloPulse1 
  //
  CalibCalPulse1Event *cp1 = 0;
  TTree *tr = 0;
  EventHeader *eh = 0;
  PscuHeader *ph = 0;
  //
  UInt_t nevents = 0;
  UInt_t fromtime = 0;
  UInt_t totime = 0;
  UInt_t obt = 0;
  UInt_t pkt = 0;
  //
  tr = (TTree*)file->Get("CalibCalPulse1");
  if ( !tr || tr->IsZombie() ) throw -31;
  //
  tr->SetBranchAddress("CalibCalPulse1", &cp1);
  tr->SetBranchAddress("Header", &eh);
  nevents = tr->GetEntries();
  //
  Float_t totpul = 0.;
  //
  if ( nevents > 0 ){
    //
    for (UInt_t i=0; i < nevents; i++){
      tr->GetEntry(i);
      for (UInt_t section = 0; section < 4; section++){
	//
	if ( cp1->pstwerr[section] && cp1->unpackError == 0 ){
	  valid = 1;
	  if ( cp1->pperror[section] ) valid = 0;
	  //
	  // check pulse values for one plane, if all zeros calibration is not valid (calorimeter power problems) [8th data reduction bug, fixed on 25/11/2009 by E.M.]
	  //
	  totpul = 0.;
	  Int_t ns = 0;
	  if ( section == 2 ) ns = 3; 
	  if ( section == 3 ) ns = 1; 
	  if ( section == 1 ) ns = 2; 
	  for (UInt_t ss=0; ss<96; ss++){
	    totpul += cp1->calpuls[ns][0][ss];
	  }
	  if ( totpul >= 3145632. ){
	    if ( IsDebug() ) printf(" PULSE1 Section %i totpul %f -  No calibration data! Calorimeter power problems? \n",section,totpul);
	    valid = 0;
	  };
	  //
	  ph = eh->GetPscuHeader();
	  obt = ph->GetOrbitalTime();  
	  pkt = ph->GetCounter();  
	  fromtime = this->GetAbsTime(ph->GetOrbitalTime());  
	  if ( this->PKT(pkt) >= this->PKT(pktfirst) && this->PKT(pkt) <= upperpkt && this->OBT(obt) >= this->OBT(obtfirst) && this->OBT(obt) <= upperobt ){
	    //	  if ( this->PKT(pkt) >= this->PKT(pktfirst) && this->OBT(obt) >= this->OBT(obtfirst) ){
	    //
	    if ( IsDebug() ) printf(" Calo pulse1 calibration for section %i at time %u obt %u pkt %u \n",section,fromtime,obt,pkt);
	    //
	    // check if the calibration has already been inserted
	    //
	    oss.str("");
	    oss << " SELECT ID FROM GL_CALOPULSE_CALIB WHERE "
		<< " SECTION = "<< section << " AND "
		<< " PULSE_AMPLITUDE = 0 AND "
		<< " BOOT_NUMBER = "<< this->GetBOOTnumber() << " AND "
		<< " OBT = "<< obt << " AND "
		<< " PKT = "<< pkt << ";";
	    //
	    if ( IsDebug() ) printf(" Check if the calo pulse1 calibration has already been inserted: query is \n %s \n",oss.str().c_str());
	    result = conn->Query(oss.str().c_str());
	    //
	    if ( !result ) throw -4;
	    //
	    row = result->Next();
	    //
	    if ( row ){
	      //
	      if ( IsDebug() ) printf(" Calo pulse1 calibration already inserted in the DB\n");
	      if ( PEDANTIC ) throw -75;
	      //
	    } else {
	      //
	      // we have to insert a new calibration, check where to place it
	      //
	      oss.str("");
	      oss << " SELECT ID,TO_TIME FROM GL_CALOPULSE_CALIB WHERE "
		  << " SECTION = "<< section << " AND "
		  << " PULSE_AMPLITUDE = 0 AND "
		  << " SECTION = "<< section << " AND "
		  << " FROM_TIME < "<< fromtime << " AND "
		  << " TO_TIME > "<< fromtime << ";";
	      //
	      if ( IsDebug() ) printf(" Check where to place the pulse1 calo calibration: query is \n %s \n",oss.str().c_str());
	      result = conn->Query(oss.str().c_str());
	      //
	      if ( !result ) throw -4;
	      //
	      row = result->Next();
	      //
	      if ( !row ){
		//
		// no calibrations in the db contain our calibration
		//
		if ( IsDebug() ) printf(" Pulse1 calibration with fromtime lower than others to be inserted in the DB for section %i \n",section);
		if ( fromtime < 1150871000 ){ //1150866904
		  if ( IsDebug() ) printf(" First PAMELA flight calibration at time %u \n",fromtime);
		  fromtime = 0;// the first flight calibration was taken at about  1156429100 s, this line allow to analyze first runs in raw mode
		};
		//
		oss.str("");
		oss << " SELECT FROM_TIME FROM GL_CALOPULSE_CALIB WHERE "
		    << " PULSE_AMPLITUDE = 0 AND "
		    << " SECTION = "<< section << " AND "
		    << " FROM_TIME > "<< fromtime << " ORDER BY FROM_TIME ASC LIMIT 1;";
		//
		if ( IsDebug() ) printf(" Check the upper limit for pulse1 calibration: query is \n %s \n",oss.str().c_str());
		result = conn->Query(oss.str().c_str());
		//
		if ( !result ) throw -4;
		//
		row = result->Next();
		if ( !row ){
		  totime = numeric_limits<UInt_t>::max();
		} else {
		  totime = (UInt_t)atoll(row->GetField(0));
		};
		//
	      } else {
		//
		// determine upper and lower limits and make space for the new calibration
		//
		totime = (UInt_t)atoll(row->GetField(1));
		//
		oss.str("");
		oss << " UPDATE GL_CALOPULSE_CALIB SET "   
		    << " TO_TIME = "<< fromtime << " WHERE "  // NOTICE: to_time is equal to from_time of the calibration before, so the interval is: [from_time,to_time[
		    << " ID = "<< row->GetField(0) << ";";
		//
		if ( IsDebug() ) printf(" Make space for the new pulse1 calibration: query is \n %s \n",oss.str().c_str());
		result = conn->Query(oss.str().c_str());
		//
		if ( !result ) throw -4;
		//
	      };
	      //
	      oss.str("");
	      oss << " INSERT INTO GL_CALOPULSE_CALIB (ID,ID_ROOT_L0,EV_ROOT,FROM_TIME,TO_TIME,SECTION,PULSED_STRIP,PULSE_AMPLITUDE,OBT,PKT,BOOT_NUMBER,VALIDATION) "
		  << " VALUES (NULL,' "
		  << idroot << "','"
		  << i << "','"
		  << fromtime << "','"
		  << totime << "','"
		  << section << "',NULL,'0','"
		  << obt << "','"
		  << pkt << "','"
		  << this->GetBOOTnumber() << "','"
		  << valid << "');";
	      //
	      if ( IsDebug() ) printf(" Insert the new pulse1 calibration: query is \n %s \n",oss.str().c_str());
	      //
	      result = conn->Query(oss.str().c_str());
	      //
	      if ( !result ) throw -4;
	      //
	    };
	    //
	  } else {
	    //
	    if ( IsDebug() ) printf(" Pulse1 calo calibration for section %i at time %u obt %u pkt %u OUTSIDE the considered time interval \n",section,fromtime,obt,pkt);
	    //	    if ( PEDANTIC ) throw -76;
	    //
	  };      
	  //      
	};
      };
    };
  };
  //
  // CaloPulse2
  //
  tr->Reset();
  CalibCalPulse2Event *cp2 = 0;
  tr = 0;
  //
  nevents = 0;
  fromtime = 0;
  totime = 0;
  obt = 0;
  pkt = 0;
  //
  tr = (TTree*)file->Get("CalibCalPulse2");
  if ( !tr || tr->IsZombie() ) throw -32;
  //
  tr->SetBranchAddress("CalibCalPulse2", &cp2);
  tr->SetBranchAddress("Header", &eh);
  nevents = tr->GetEntries();
  //
  if ( nevents > 0 ){
    //
    for (UInt_t i=0; i < nevents; i++){
      tr->GetEntry(i);
      for (UInt_t section = 0; section < 4; section++){
	//
	if ( cp2->pstwerr[section] && cp2->unpackError == 0 ){
	  valid = 1;
	  if ( cp2->pperror[section] ) valid = 0;
	  //
	  // check pulse values for one plane, if all zeros calibration is not valid (calorimeter power problems) [8th data reduction bug, fixed on 25/11/2009 by E.M.]
	  //
	  totpul = 0.;
	  Int_t ns = 0;
	  if ( section == 2 ) ns = 3; 
	  if ( section == 3 ) ns = 1; 
	  if ( section == 1 ) ns = 2; 
	  for (UInt_t ss=0; ss<96; ss++){
	    totpul += cp2->calpuls[ns][0][ss];
	  }
	  if ( totpul >= 3145632. ){
	    if ( IsDebug() ) printf(" PULSE2 Section %i totpul %f -  No calibration data! Calorimeter power problems? \n",section,totpul);
	    valid = 0;
	  };
	  //
	  ph = eh->GetPscuHeader();
	  obt = ph->GetOrbitalTime();  
	  pkt = ph->GetCounter();  
	  fromtime = this->GetAbsTime(ph->GetOrbitalTime());  
	  if ( this->PKT(pkt) >= this->PKT(pktfirst) && this->PKT(pkt) <= upperpkt && this->OBT(obt) >= this->OBT(obtfirst) && this->OBT(obt) <= upperobt ){
	    //	  if ( this->PKT(pkt) >= this->PKT(pktfirst) && this->OBT(obt) >= this->OBT(obtfirst) ){
	    //
	    if ( IsDebug() ) printf(" Calo pulse2 calibration for section %i at time %u obt %u pkt %u \n",section,fromtime,obt,pkt);
	    //
	    // check if the calibration has already been inserted
	    //
	    oss.str("");
	    oss << " SELECT ID FROM GL_CALOPULSE_CALIB WHERE "
		<< " SECTION = "<< section << " AND "
		<< " PULSE_AMPLITUDE != 0 AND "
		<< " BOOT_NUMBER = "<< this->GetBOOTnumber() << " AND "
		<< " OBT = "<< obt << " AND "
		<< " PKT = "<< pkt << ";";
	    //
	    if ( IsDebug() ) printf(" Check if the calo pulse2 calibration has already been inserted: query is \n %s \n",oss.str().c_str());
	    result = conn->Query(oss.str().c_str());
	    //
	    if ( !result ) throw -4;
	    //
	    row = result->Next();
	    //
	    if ( row ){
	      //
	      if ( IsDebug() ) printf(" Calo pulse2 calibration already inserted in the DB\n");
	      if ( PEDANTIC ) throw -77;
	      //
	    } else {
	      //
	      // we have to insert a new calibration
	      //
	      //
	      // Determine the amplitude of the pulse
	      //
	      UInt_t pampli = 1;
	      UInt_t pstrip = 0;
	      UInt_t se = 0;
	      if ( section == 1 ) se = 2;
	      if ( section == 2 ) se = 3;
	      if ( section == 3 ) se = 1;
	      for (Int_t ii=0;ii<16;ii++){
		if ( cp2->calpuls[se][0][ii] > 10000. ){
		  pampli = 2;
		  pstrip = ii;
		};
	      }; 
	      if ( pampli == 1 ){
		Bool_t found = false;
		Float_t delta=0.;
		UInt_t cstr = 0;
		while ( !found && cstr < 16 ){
		  for (Int_t ii=0;ii<16;ii++){
		    delta = cp2->calpuls[se][0][ii] - cp2->calpuls[se][0][cstr];
		    if ( IsDebug() ) printf(" cstr is %u ii is %i delta is %f \n",cstr,ii,delta);
		    if ( delta > 500. ){
		      pampli = 1;
		      pstrip = ii;
		      found = true;
		      if ( IsDebug() ) printf(" FOUND cstr is %u ii is %i delta is %f \n",cstr,ii,delta);
		    };
		  };
		  cstr++;
		};
		if ( !found ) pstrip = 100;
	      };
	      if ( IsDebug() ) printf(" The amplitude of the pulser is %u (where 1 = low pulse, 2 = high pulse), pulsed strip is %u \n",pampli,pstrip);
	      //
	      // we have to insert a new calibration, check where to place it
	      //
	      oss.str("");
	      oss << " SELECT ID,TO_TIME FROM GL_CALOPULSE_CALIB WHERE "
		  << " SECTION = "<< section << " AND "
		  << " PULSE_AMPLITUDE = " << pampli << " AND "
		  << " SECTION = "<< section << " AND "
		  << " FROM_TIME < "<< fromtime << " AND "
		  << " TO_TIME > "<< fromtime << ";";
	      //
	      if ( IsDebug() ) printf(" Check where to place the pulse2 calo calibration: query is \n %s \n",oss.str().c_str());
	      result = conn->Query(oss.str().c_str());
	      //
	      if ( !result ) throw -4;
	      //
	      row = result->Next();
	      //
	      if ( !row ){
		//
		// no calibrations in the db contain our calibration
		//
		if ( IsDebug() ) printf(" Pulse2 calibration with fromtime lower than others to be inserted in the DB for section %i \n",section);
		if ( fromtime < 1150871000 ){ //1150866904
		  if ( IsDebug() ) printf(" First PAMELA flight calibration at time %u \n",fromtime);
		  fromtime = 0;// the first flight calibration was taken at about  1156429100 s, this line allow to analyze first runs in raw mode
		};
		//
		oss.str("");
		oss << " SELECT FROM_TIME FROM GL_CALOPULSE_CALIB WHERE "
		    << " PULSE_AMPLITUDE = " << pampli << " AND "
		    << " SECTION = "<< section << " AND "
		    << " FROM_TIME > "<< fromtime << " ORDER BY FROM_TIME ASC LIMIT 1;";
		//
		if ( IsDebug() ) printf(" Check the upper limit for pulse2 calibration: query is \n %s \n",oss.str().c_str());
		result = conn->Query(oss.str().c_str());
		//
		if ( !result ) throw -4;
		//
		row = result->Next();
		if ( !row ){
		  totime = numeric_limits<UInt_t>::max();
		} else {
		  totime = (UInt_t)atoll(row->GetField(0));
		};
		//
	      } else {
		//
		// determine upper and lower limits and make space for the new calibration
		//
		totime = (UInt_t)atoll(row->GetField(1));
		//
		oss.str("");
		oss << " UPDATE GL_CALOPULSE_CALIB SET "   
		    << " TO_TIME = "<< fromtime << " WHERE "  // NOTICE: to_time is equal to from_time of the calibration before, so the interval is: [from_time,to_time[
		    << " ID = "<< row->GetField(0) << ";";
		//
		if ( IsDebug() ) printf(" Make space for the new pulse2 calibration: query is \n %s \n",oss.str().c_str());
		result = conn->Query(oss.str().c_str());
		//
		if ( !result ) throw -4;
		//
	      };
	      //
	      // Fill the DB
	      //
	      oss.str("");
	      //	      oss << " INSERT INTO GL_CALOPULSE_CALIB (ID,ID_ROOT_L0,EV_ROOT,FROM_TIME,TO_TIME,SECTION,OBT,PKT,BOOT_NUMBER,VALIDATION) "
	      oss << " INSERT INTO GL_CALOPULSE_CALIB (ID,ID_ROOT_L0,EV_ROOT,FROM_TIME,TO_TIME,SECTION,PULSED_STRIP,PULSE_AMPLITUDE,OBT,PKT,BOOT_NUMBER,VALIDATION) "
		  << " VALUES (NULL,' "
		  << idroot << "','"
		  << i << "','"
		  << fromtime << "','"
		  << totime << "','"
		  << section << "','"
		  << pstrip << "','"
		  << pampli << "','"
		  << obt << "','"
		  << pkt << "','"
		  << this->GetBOOTnumber() << "','"
		  << valid << "');";
	      //
	      if ( IsDebug() ) printf(" Insert the new pulse2 calibration: query is \n %s \n",oss.str().c_str());
	      //
	      result = conn->Query(oss.str().c_str());
	      //
	      if ( !result ) throw -4;
	      //
	    };
	    //
	  } else {
	    //
	    if ( IsDebug() ) printf(" Pulse2 calo calibration for section %i at time %u obt %u pkt %u OUTSIDE the considered time interval \n",section,fromtime,obt,pkt);
	    //	    if ( PEDANTIC ) throw -78;
	    //
	  };      
	  //      
	};
      };
    };
  };
  //
  return(0);
};

/**
 * Fill the GL_TRK_CALIB table
 */
void PamelaDBOperations::HandleTRK_CALIB(Bool_t pk1, Bool_t pk2){
    
    GL_TRK_CALIB *glcal = new GL_TRK_CALIB();
    //
    glcal->ID         = 0;
    glcal->ID_ROOT_L0 = GetID_ROOT();
    glcal->EV_ROOT_CALIBTRK1 = t1;
    glcal->EV_ROOT_CALIBTRK2 = t2;
    glcal->FROM_TIME = fromtime;
    glcal->TO_TIME   = 0;
    glcal->OBT1      = obt1;
    glcal->OBT2      = obt2;
    glcal->PKT1      = pkt1;
    glcal->PKT2      = pkt2;
    glcal->BOOT_NUMBER = GetBOOTnumber();
    glcal->VALIDATION = valid;
    //
    HandleTRK_CALIB(glcal);
    //
    delete glcal;
}
/**
 * Fill the GL_TRK_CALIB table
 */
void PamelaDBOperations::HandleTRK_CALIB(GL_TRK_CALIB *glcal){

    Bool_t pk1 = (glcal->OBT1>0&&glcal->PKT1>0);
    Bool_t pk2 = (glcal->OBT2>0&&glcal->PKT2>0);
    UInt_t boot_number = glcal->BOOT_NUMBER;
    UInt_t obt1 = glcal->OBT1;
    UInt_t obt2 = glcal->OBT2;
    UInt_t pkt1 = glcal->PKT1;
    UInt_t pkt2 = glcal->PKT2;
    UInt_t fromtime = glcal->FROM_TIME;
    UInt_t totime = 0;
    UInt_t idroot = glcal->ID_ROOT_L0;
    UInt_t t1 = glcal->EV_ROOT_CALIBTRK1;
    UInt_t t2 = glcal->EV_ROOT_CALIBTRK2;
    UInt_t valid = glcal->VALIDATION;
    //
    TSQLResult *result = 0;
    TSQLRow    *row    = 0;
    //
    stringstream oss;
    oss.str("");
    //
    //
    if ( !pk1 && !pk2 ){
	if ( IsDebug() ) printf(" Cannot handle trk calibration with both packet missing!\n");
	return;
    };
    //
    // check if the calibration has already been inserted
    //
    oss.str("");
    oss << " SELECT ID FROM GL_TRK_CALIB WHERE "
	<< " BOOT_NUMBER = "<< boot_number; // 
    oss << " AND FROM_TIME="<<fromtime; /// NEWNEWNEW -- VA BENE ?!?!?!?!
    oss << " AND ( ( ";   
    if ( pk1 ){
	oss << " OBT1 = "<< obt1 << " AND "
	    << " PKT1 = "<< pkt1
	    << " ) OR ( ";
    } else {
	oss << " PKT1 = "<< pkt2-1
	    << " ) OR ( ";   
    };      
    if ( pk2 ){
	oss << " OBT2 = "<< obt2 << " AND "
	    << " PKT2 = "<< pkt2;
    } else {
	oss << " PKT2 = "<< pkt1+1;
    };      
    oss << " ) );";   
    //
    if ( IsDebug() ) printf(" Check if the trk calibration has already been inserted: query is \n %s \n",oss.str().c_str());
    result = conn->Query(oss.str().c_str());
    //
    if ( !result ) throw -4;
    //
    row = result->Next();
    //
    if ( row ){
	//
	if ( IsDebug() ) printf(" Trk calibration already inserted in the DB\n");
	if ( PEDANTIC ) throw -80;
	//
    } else {
	//
	// we have to insert a new calibration, check where to place it
	//
	oss.str("");
	oss << " SELECT ID,TO_TIME FROM GL_TRK_CALIB WHERE "
	    << " FROM_TIME < "<< fromtime << " AND "
	    << " TO_TIME > "<< fromtime << ";";
	//
	if ( IsDebug() ) printf(" Check where to place the trk calibration: query is \n %s \n",oss.str().c_str());
	result = conn->Query(oss.str().c_str());
	//
	if ( !result ) throw -4;
	//
	row = result->Next();
	//
	if ( !row ){
	    //
	    // no calibrations in the db contain our calibration
	    //
	    if ( IsDebug() ) printf(" Calibration with fromtime lower than others to be inserted in the DB\n");
	    if ( fromtime < 1150871000 ) fromtime = 0; // the first flight calibration was taken at about 1150863300 s, this line allows to analyze first runs in raw mode
	    //
	    oss.str("");
	    oss << " SELECT FROM_TIME FROM GL_TRK_CALIB WHERE "
		<< " FROM_TIME > "<< fromtime << " ORDER BY FROM_TIME ASC LIMIT 1;";
	    //
	    if ( IsDebug() ) printf(" Check the upper limit for calibration: query is \n %s \n",oss.str().c_str());
	    result = conn->Query(oss.str().c_str());
	    //
	    if ( !result ) throw -4;
	    //
	    row = result->Next();
	    if ( !row ){
		totime = numeric_limits<UInt_t>::max();
	    } else {
		totime = (UInt_t)atoll(row->GetField(0));
	    };
	    //
	} else {
	    //
	    // determine upper and lower limits and make space for the new calibration
	    //
	    totime = (UInt_t)atoll(row->GetField(1));
	    //
	    oss.str("");
	    oss << " UPDATE GL_TRK_CALIB SET "   
		<< " TO_TIME = "<< fromtime << " WHERE "  // NOTICE: to_time is equal to from_time of the calibration before, so the interval is: [from_time,to_time[
		<< " ID = "<< row->GetField(0) << ";";
	    //
	    if ( IsDebug() ) printf(" Make space for the new trk calibration: query is \n %s \n",oss.str().c_str());
	    result = conn->Query(oss.str().c_str());
	    //
	    if ( !result ) throw -4;
	    //
	};
	//
	oss.str("");
	oss << " INSERT INTO GL_TRK_CALIB (ID,ID_ROOT_L0,EV_ROOT_CALIBTRK1,EV_ROOT_CALIBTRK2,FROM_TIME,TO_TIME,OBT1,PKT1,OBT2,PKT2,BOOT_NUMBER,VALIDATION) "
	    << " VALUES (NULL,' "
	    << idroot << "',";
	//
	if ( !pk1 ){
	    oss << "NULL,";
	} else {
	    oss << "'"
		<< t1 << "',";
	};
	//
	if ( !pk2 ){
	    oss << "NULL,'";
	} else {
	    oss << "'"
		<< t2 << "','";
	};
	//
	oss << fromtime << "','"
	    << totime << "','"
	    << obt1 << "','"
	    << pkt1 << "','"
	    << obt2 << "','"
	    << pkt2 << "','"
	    << boot_number << "','"
	    << valid << "');";
	//
	if ( IsDebug() ) printf(" Insert the new trk calibration: query is \n %s \n",oss.str().c_str());
	//
	result = conn->Query(oss.str().c_str());
	//
	if ( !result ) throw -4;
	//
    };
    
    oss.str("");
    oss << " SELECT ID FROM GL_TRK_CALIB ORDER BY ID DESC LIMIT 1 ;";	
    if ( IsDebug() ) cout << oss.str().c_str() << endl;
    result = conn->Query(oss.str().c_str());
    if ( !result ) throw -4;;
    row = result->Next();
    if(row)glcal->ID = (UInt_t)atoll(row->GetField(0));
    //
    delete result; // mmm... "Error in <TMySQLResult::Next>: result set closed" solved? 090112 [8RED error messages]
    //
};

/**
 * Scan tracker calibrations packets, fill the GL_TRK_CALIB table
 */
Int_t PamelaDBOperations::insertTRK_CALIB(){
    //
    CalibTrk1Event *caltrk1 = 0;
    CalibTrk2Event *caltrk2 = 0;
    TTree *tr1 = 0;
    TTree *tr2 = 0;
    EventHeader *eh1 = 0;
    PscuHeader *ph1 = 0;
    EventHeader *eh2 = 0;
    PscuHeader *ph2 = 0;
    //
    PacketType *pctp=0;
    EventCounter *codt2=0;
    //
    Int_t nevents1 = 0;
    Int_t nevents2 = 0;
    //
    fromtime = 0;
    //
    obt1 = 0;
    pkt1 = 0;
    obt2 = 0;
    pkt2 = 0;
    //
    tr1 = (TTree*)file->Get("CalibTrk1");
    if ( !tr1 || tr1->IsZombie() ) throw -22;
    tr2 = (TTree*)file->Get("CalibTrk2");
    if ( !tr2 || tr2->IsZombie() ) throw -23;
    //
    tr1->SetBranchAddress("CalibTrk1", &caltrk1);
    tr1->SetBranchAddress("Header", &eh1);
    nevents1 = tr1->GetEntries();
    tr2->SetBranchAddress("CalibTrk2", &caltrk2);
    tr2->SetBranchAddress("Header", &eh2);
    nevents2 = tr2->GetEntries();
    //
    if ( !nevents1 && !nevents2 ) return(1);
    //
    t2 = -1;
    Int_t pret2 = 0;
    Int_t t2t1cal = 0;
    //
    bool MISSING_pkt1 = true;
    bool MISSING_pkt2 = true;
    int  ncalib = 0;
    bool try_to_recover = false;
    //
    for (t1=0; t1 < nevents1; t1++){//loop over packet1
	//
	pret2 = t2;
	tr1->GetEntry(t1);
	//
	ph1 = eh1->GetPscuHeader();
	obt1 = ph1->GetOrbitalTime();  
	pkt1 = ph1->GetCounter();  
	fromtime = GetAbsTime(ph1->GetOrbitalTime());  
	//
	// chek if the packet number and obt are consistent with the other packets ???
	//
	if ( PKT(pkt1) >= PKT(pktfirst) && PKT(pkt1) <= upperpkt && OBT(obt1) >= OBT(obtfirst) && OBT(obt1) <= upperobt ){
	    //    if ( this->PKT(pkt1) >= this->PKT(pktfirst) && this->OBT(obt1) >= this->OBT(obtfirst) ){
	    //
	    if ( IsDebug() ) printf("\n Trk calibration1 %u at time %u obt %u pkt %u \n",t1,fromtime,obt1,pkt1);
	    //      
	    valid = ValidateTrkCalib( caltrk1, eh1 );
	    if ( IsDebug() ) cout << " pkt1 validation --> "<<valid<<endl;
	    //
	    // Do we have the second calibration packet?
	    //
	    if ( IsDebug() ) cout << " Loop over calibration2 to search associated calibration: "<<endl;
	    while ( t2t1cal < t1+1 ){ // get the calibration packet2 that follows the packet1
		//
		t2++;
		//
		pret2 = t2 - 1; // EMILIANO
		//
		if ( t2 < nevents2 ){
		    tr2->GetEntry(t2);
		    codt2 = eh2->GetCounter();
		    t2t1cal = codt2->Get(pctp->CalibTrk1);
		    //
		    ph2 = eh2->GetPscuHeader();
		    obt2 = ph2->GetOrbitalTime();  
		    pkt2 = ph2->GetCounter();  
		    //
		    if ( IsDebug() ) printf(" >> trk calibration2 at obt %u pkt %u t2 is %u , t2t1cal is %u \n",obt2,pkt2,t2,t2t1cal);	  
		    //	  if ( caltrk2->unpackError != 0 || caltrk2->good0 == 0 ) valid = 0; // CONDITIONS ON THE GOODNESS OF THE CALIBRATION PKT2
		    //	  
		} else {
		    //
		    // running out of vector without finding the corresponding calibration, sig
		    //
		    if ( IsDebug() ) printf(" t2 >= nevents2 \n");
		    pret2 = t2;
		    obt2 = 0;
		    //	  pkt2 = pkt1+2;
		    pkt2 = 0;
		    t2t1cal = t1+1;
		};
		//	if ( (this->PKT(pkt2) < this->PKT(pktfirst) || this->PKT(pkt2) > upperpkt) && (this->OBT(obt2) < this->OBT(obtfirst) || this->OBT(obt2) > upperobt) ){

		// EMILIANO
		// 	if ( (this->PKT(pkt2) < this->PKT(pktfirst) || this->PKT(pkt2) > upperpkt) || (this->OBT(obt2) < this->OBT(obtfirst) || this->OBT(obt2) > upperobt) ){
		// 	  //	if ( this->PKT(pkt2) < this->PKT(pktfirst) && this->OBT(obt2) < this->OBT(obtfirst) ){
		// 	  if ( IsDebug() ) printf(" running out of vector without finding the corresponding calibration, sig \n");
		// 	  //
		// 	  // running out of vector without finding the corresponding calibration, sig
		// 	  //
		// 	  pret2 = t2;
		// 	  obt2 = 0;
		// 	  //	  pkt2 = pkt1+2;
		// 	  pkt2 = 0;
		// 	  t2t1cal = t1+1;
		// 	};


		//
	    };
	    //
	    if ( IsDebug() ) printf(" Check if trk calibration2 is the right one \n");
	    //
	    // EMILIANO
	    if ( ( PKT(pkt2) < PKT(pktfirst) || PKT(pkt2) > upperpkt) || (OBT(obt2) < OBT(obtfirst) || OBT(obt2) > upperobt) ){
		//	if ( this->PKT(pkt2) < this->PKT(pktfirst) && this->OBT(obt2) < this->OBT(obtfirst) ){
		if ( IsDebug() ) printf(" *WARNING*  The calibration found is outside the interval, sig \n");
		//
		// running out of vector without finding the corresponding calibration, sig
		//
		pret2 = t2;
		obt2 = 0;
		pkt2 = 0;
	    };
	    if ( PKT(pkt2) == PKT(pkt1)+1 ){
		if ( IsDebug() ) cout << " ...OK"<<endl;
		// =======================
		// The calibration is good
		// =======================
		//
//	if ( IsDebug() ) printf(" Found trk calibration2 at obt %u pkt %u t2 is %u \n",obt2,pkt2,t2);
//	if ( IsDebug() ) printf(" Trk calibration2 at obt %u pkt %u t2 is %u is good \n",obt2,pkt2,t2);
//        if ( IsDebug() ) printf("\n Trk calibration2 at time %u obt %u pkt %u \n",fromtime,obt2,pkt2);
		if ( IsDebug() ) printf(" Trk calibration2 %u at time %u obt %u pkt %u \n",t2,fromtime,obt2,pkt2);
		//
		UInt_t valid2 = ValidateTrkCalib( caltrk2, eh2 );
		if ( IsDebug() ) cout << " pkt2 validation --> "<<valid2<<endl;
//	valid = valid & valid2;
		valid = valid & valid2; //QUESTO VA CAMBIATO
		//
		// Handle good calib
		//
		MISSING_pkt1 = false;
		MISSING_pkt2 = false;
// 		this->HandleTRK_CALIB(!MISSING_pkt1,!MISSING_pkt2); 
		//
		// Check for missing calibtrk1
		//
		if ( t2 != pret2+1 ){
		    //
		    if ( IsDebug() ) printf(" Missing the trk calibration1! Next one at obt %u pkt %u t2 is %u pret2 is %u \n",obt2,pkt2,t2,pret2);
		    //
		    while ( t2 > pret2+1 ){
			//
			// handle missing calib1
			//
			pret2++;
			//
			obt1 = 0;
			pkt1 = 0;
			//
			tr2->GetEntry(pret2);
			ph2 = eh2->GetPscuHeader();
			obt2 = ph2->GetOrbitalTime();  
			pkt2 = ph2->GetCounter();  
			//
			fromtime = this->GetAbsTime(ph2->GetOrbitalTime()); 
			//
			valid = 0;
			MISSING_pkt1 = true;
			MISSING_pkt2 = false;
// 			this->HandleTRK_CALIB(!MISSING_pkt1,!MISSING_pkt2); 
			//
		    };
		    //
		};
		//
	    } else if ( this->PKT(pkt2) > this->PKT(pkt1)+1 ){
		//
		// Check for missing calibtrk2
		//
		if ( IsDebug() ) printf(" Missing the trk calibration2! Next one at obt %u pkt %u t2 is %u\n",obt2,pkt2,t2);
		t2 = pret2;
		//
		// handle missing calib2
		//
		obt2 = 0;
		pkt2 = 0;
		valid = 0;
		MISSING_pkt1 = false;
		MISSING_pkt2 = true;
// 		this->HandleTRK_CALIB(!MISSING_pkt1,!MISSING_pkt2); 
		//
	    };
	    //

	    if( !(MISSING_pkt1&MISSING_pkt2) ){
	      this->HandleTRK_CALIB(!MISSING_pkt1,!MISSING_pkt2); 
	      ncalib++;
	      if( MISSING_pkt1||MISSING_pkt2||!valid )try_to_recover=true;
	    }


	} else {
	  //
	    if ( IsDebug() ) printf(" Trk calibration1 at time %u obt %u pkt %u OUTSIDE the considered time interval \n",fromtime,obt1,pkt1);
	    //      if ( PEDANTIC ) throw -79;
	    //
	};
	//    

    }; //end loop on pkt1



    //
    // we have one more calib pkt2 !
    //
    t2++;
    while ( t2 < nevents2 ){
	//
	// handle missing calib1
	//
	if ( IsDebug() ) printf(" t2 is %u nevents2 is %u \n",t2,nevents2);
	obt1 = 0;
	pkt1 = 0;
	//
	tr2->GetEntry(t2);
	ph2 = eh2->GetPscuHeader();
	obt2 = ph2->GetOrbitalTime();  
	pkt2 = ph2->GetCounter();  
	//
	fromtime = this->GetAbsTime(ph2->GetOrbitalTime()); 
	valid = 0;
	//  if ( this->PKT(pkt1) >= this->PKT(pktfirst) && this->PKT(pkt1) <= upperpkt && this->OBT(obt1) >= this->OBT(obtfirst) && this->OBT(obt1) <= upperobt ){
	// EMILIANO
	if ( this->PKT(pkt2) >= this->PKT(pktfirst) && this->PKT(pkt2 <= upperpkt) && this->OBT(obt2) >= this->OBT(obtfirst) && this->OBT(obt2) <= upperobt ){
	    //    if ( this->PKT(pkt2) > this->PKT(pktfirst) || this->OBT(obt2) > this->OBT(obtfirst) ){
	    //
	    if ( IsDebug() ) printf(" Missing the trk calibration1! Next one at obt %u pkt %u t2 is %u\n",obt2,pkt2,t2);
	    //
	    MISSING_pkt1 = true;
	    MISSING_pkt2 = false;
	    this->HandleTRK_CALIB(!MISSING_pkt1,!MISSING_pkt2); 
	    ncalib++;
	    if( MISSING_pkt1||MISSING_pkt2||!valid )try_to_recover=true;
	    //
	};
	//
	t2++;
	//
    };

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
// -----------------------------------------------------------------
// in case of corruption, check if the calibration can be recovered 
// from another chewbacca file
// -----------------------------------------------------------------
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    

//    cout <<" TRY TO RECOVER ?? "<<try_to_recover<<endl;
    
    if(chewbacca&&try_to_recover){


	if ( IsDebug() ) cout << endl << ">>>> TRY TO RECOVER TRACKER CALIBRATIONS <<<<"<<endl;

	TSQLResult *rresult = 0; // 10RED bug, result is re-used inside result looop...
	TSQLResult *result = 0; // 10RED bug, result is re-used inside result looop...
	TSQLRow    *row    = 0;
	//
	stringstream oss;
	oss.str("");
	//

	////////////////////////////////////////////////////////////////////////
	// retrieve the name of the current file:
	////////////////////////////////////////////////////////////////////////	
	oss.str("");
	oss << "SELECT NAME FROM GL_ROOT where ID=" << GetID_ROOT() <<";";
	if ( IsDebug() ) cout << oss.str().c_str() << endl;

	result = conn->Query(oss.str().c_str());
	if ( !result ) throw -4;;
	row = result->Next();
	TString thisfilename = (TString)row->GetField(0);
	if ( IsDebug() ) cout << "Current file ==> "<<thisfilename<<endl;	

	////////////////////////////////////////////////////////////////////////	
	// read all the calibrations inserted
	////////////////////////////////////////////////////////////////////////	
	oss.str("");
	oss << " SELECT ";
	oss << " ID,FROM_TIME,OBT1,PKT1,OBT2,PKT2,BOOT_NUMBER,VALIDATION,EV_ROOT_CALIBTRK1,EV_ROOT_CALIBTRK2,TO_TIME";
	oss << " FROM GL_TRK_CALIB ";
	oss << " ORDER BY ID DESC LIMIT "<<ncalib<<"; ";	
	if ( IsDebug() ) cout << oss.str().c_str() << endl;

	rresult = conn->Query(oss.str().c_str());
	if ( !result ) throw -4;;
	if ( IsDebug() ) cout <<"Rows: "<<result->GetRowCount()<<endl;
	
	// -----------------------------------
	// loop over calibrations ...
	// -----------------------------------
	UInt_t nn=0;
	do {
            row = rresult->Next();
	    if(!row)break;
	    
	    UInt_t id       = (UInt_t)atoll(row->GetField(0));
	    UInt_t fromtime = (UInt_t)atoll(row->GetField(1));
	    UInt_t obt1     = (UInt_t)atoll(row->GetField(2));
	    UInt_t pkt1     = (UInt_t)atoll(row->GetField(3));
	    UInt_t obt2     = (UInt_t)atoll(row->GetField(4));
	    UInt_t pkt2     = (UInt_t)atoll(row->GetField(5));
	    UInt_t boot     = (UInt_t)atoll(row->GetField(6));
	    UInt_t valid    = (UInt_t)atoll(row->GetField(7));
	    bool MISSING_pkt1 = (row->GetFieldLength(8)==0);
	    bool MISSING_pkt2 = (row->GetFieldLength(9)==0);
	    UInt_t totime   = (UInt_t)atoll(row->GetField(10));

	    // -------------------------------------
	    // ...check if the entry is corrupted...
	    // -------------------------------------
	    cout <<"*** "<< MISSING_pkt1 << MISSING_pkt2 << valid <<endl;
	    bool CORRUPTED = (MISSING_pkt1||MISSING_pkt2||!valid);

	    if ( IsDebug() ) cout << "("<<nn<<")  ID = "<<id<<" from GL_TRK_CALIB  ==>  corrupted ? "<<CORRUPTED<<endl;

//	    if( !CORRUPTED  )continue; // nothing to do

	    /////////////////////////////////////////////////////////	
	    // if it is corrupted, ...look for ather chewbacca files 
	    // containing the same calibrations ...
	    /////////////////////////////////////////////////////////

	    bool this_MISSING_pkt1 = false;
	    bool this_MISSING_pkt2 = false;
	    int  this_t1=0;
	    int  this_t2=0;;
	    UInt_t this_valid = 0;

	    TString path       = "";
	    TString name       = "";
	    TString raw        = "";
            //	    UInt_t obt0        = 0;
            //	    UInt_t timesync    = 0;
            //	    UInt_t boot_number = 0;
	    bool   FOUND       = false;

	    if ( IsDebug() ) cout << "------------------------------------------------------------" <<endl;

//	    for(int itable=0; itable<2; itable++){
	    for(int itable=0; itable<1; itable++){

		// ------------------------------------------------------
		// loop over both ROOT_TABLE and ROOT_TABLE_BAD 
		// ------------------------------------------------------

		TString table = "ROOT_TABLE";
		if(itable==1)table = "ROOT_TABLE_BAD";

		oss.str("");
		oss << " SELECT ";
		oss << " FOLDER_NAME,FILE_NAME,OBT_TIME_SYNC,LAST_TIME_SYNC_INFO,BOOT_NUMBER,INPUT_NAME ";
		oss << " FROM "<<table;
		oss << " WHERE 1 " << endl;
		oss << " AND FILE_NAME != \""<< thisfilename<<"\"";
		if( !MISSING_pkt1 ){
		    oss << " AND ";
		    oss << " PKT_NUMBER_INIT < "<<pkt1;
		    oss << " AND ";
		    oss << " PKT_NUMBER_FINAL > "<<pkt1;
		    oss << " AND ";
		    oss << " PKT_OBT_INIT < "<<obt1;
		    oss << " AND ";
		    oss << " PKT_OBT_FINAL > "<<obt1;
		}else{
		    if(pkt2>1) pkt1 = pkt2-1;//serve dopo		    
		}
		if( !MISSING_pkt2 ){
		    oss << " AND ";
		    oss << " PKT_NUMBER_INIT < "<<pkt2;
		    oss << " AND ";
		    oss << " PKT_NUMBER_FINAL > "<<pkt2;
		    oss << " AND ";
		    oss << " PKT_OBT_INIT < "<<obt2;
		    oss << " AND ";
		    oss << " PKT_OBT_FINAL > "<<obt2;
		}else{
		    if(pkt1>0) pkt2 = pkt1+1;//serve dopo
		}
		if( boot> 0 ){
		    oss << " AND ";
		    oss << " BOOT_NUMBER = "<<boot;
		}else{
		}
		oss << " ORDER BY BAD_PKT_CALREAD ASC; ";
	    
		TSQLResult *result2 = 0;
		TSQLRow    *row2    = 0;

		if ( IsDebug() ) cout << oss.str().c_str() << endl;	    
		result2 = conn->Query(oss.str().c_str());
		if ( !result2 ) throw -4;;
		if ( IsDebug() ) cout <<"Rows: "<<result2->GetRowCount()<<endl;

		// ------------------------------------------------------
		// loop over files containing repetition (if any)
		// ------------------------------------------------------
		do {
		    row2 = result2->Next();
		    if(!row2)break;
		
		    // ------------------------------------------------------
		    // ... a repetition is found ...
		    // ------------------------------------------------------
		    path       = (TString)row2->GetField(0);
		    name       = (TString)row2->GetField(1);
		    raw        = (TString)row2->GetField(5);
                    //		    obt0        = (UInt_t)atoll(row2->GetField(2));
                    //		    timesync    = (UInt_t)atoll(row2->GetField(3));
                    //		    boot_number = (UInt_t)atoll(row2->GetField(4));
		
		    if ( IsDebug() ) cout << "- - - - - - - - - - -" <<endl;
//		    cout << path <<endl;
//		    cout << "File    : " <<name <<endl;
//		    cout << obt0 <<endl;
//		    cout << timesync <<endl;
//		    cout << "boot n. : "<<boot_number <<endl;
//		    cout << raw <<endl;

		    // ------------------------------------------------------
		    // ... retrieve the calibration packets.
		    // ------------------------------------------------------
		    if ( IsDebug() ) printf(" file is %s/%s \n",((TString)gSystem->ExpandPathName(path.Data())).Data(),name.Data());
		    TFile *file = new TFile(((TString)gSystem->ExpandPathName(path.Data()))+"/"+name); // EM, path could be symbolic and we must expand it
		    if(!file)throw -100;
		    if(file->IsZombie())throw -100;
		    //
		    tr1 = (TTree*)file->Get("CalibTrk1");
		    if ( !tr1 || tr1->IsZombie() ) throw -22;
		    tr2 = (TTree*)file->Get("CalibTrk2");
		    if ( !tr2 || tr2->IsZombie() ) throw -23;
		    //
		    tr1->SetBranchAddress("CalibTrk1", &caltrk1);
		    tr1->SetBranchAddress("Header", &eh1);
		    nevents1 = tr1->GetEntries();
		    tr2->SetBranchAddress("CalibTrk2", &caltrk2);
		    tr2->SetBranchAddress("Header", &eh2);
		    nevents2 = tr2->GetEntries();
		    for(this_t1=0; this_t1<nevents1; this_t1++){
			tr1->GetEntry(this_t1);
			if( 
			    (UInt_t)eh1->GetPscuHeader()->GetCounter() == pkt1 &&
			    true) break;
			this_MISSING_pkt1 = true;
		    }
		    for(this_t2=0; this_t2<nevents2; this_t2++){
			tr2->GetEntry(this_t2);
			if( 
			    (UInt_t)eh2->GetPscuHeader()->GetCounter() == pkt2 &&
			    true) break;
			this_MISSING_pkt2 = true;
		    }
		    this_valid = 
			ValidateTrkCalib( caltrk1, eh1, file )
			*
			ValidateTrkCalib( caltrk2, eh2, file );
			    
		    // ---------------------------------------------------------------------
		    // accept the calibration if it is better than the previous:
		    //
		    // - if the new calibration is perfect (both valid packets)
		    // - if the new calibration has both the packets and the previous does not
		    // ---------------------------------------------------------------------
		    if( 
			( !this_MISSING_pkt1&&!this_MISSING_pkt2&&this_valid )||
			( (MISSING_pkt1||MISSING_pkt2) && (!this_MISSING_pkt1&&!this_MISSING_pkt2) )||
			false)FOUND=true;	
	    
		    if(file)file->Close();

		    if(FOUND)break;

		}while(1);//endl loop over root table entries
                
                delete result2; // 10RED potential memory leak
		if(FOUND)break;

	    }//end loop over tables 

	    if(FOUND){

	      if ( IsDebug() ) cout << " >>> REPETITION FOUND :-) <<<" <<endl;

	      ////////////////////////////////////////////
	      // insert a new entry in GL_TRK_CALIB and 
	      // modify the time-tag of the previous one
	      ////////////////////////////////////////////

	      // ---------------------------------------------------------------------
	      // step 1: insert a new raw file in GL_RAW
	      // ---------------------------------------------------------------------
	      //
	      // check if the raw file already exist
	      //
	      UInt_t id_raw = 0;   // EM GL_RAW is there only for backward compatibility so we do not need to fill it when in "chewbacca" mode
	      // 		oss.str("");
	      // 		oss << "SELECT ID FROM GL_RAW where NAME=\"" << gSystem->BaseName(raw.Data()) <<"\";";
	      // 		if ( IsDebug() ) cout << oss.str().c_str() << endl;
		
	      // 		result = conn->Query(oss.str().c_str());
	      // 		if ( !result ) throw -4;;
	      // 		if ( IsDebug() ) cout <<"Rows: "<<result->GetRowCount()<<endl;
	      // 		if( result->GetRowCount() == 0){
	      // 		    if ( IsDebug() ) cout << " << Insert new RAW file >> "<<endl;
	      // 		    // - - - - - - - - - - -
	      // 		    // insert new raw file
	      // 		    // - - - - - - - - - - - 
	      // 		    GL_RAW glraw = GL_RAW();    
	      // 		    glraw.PATH        = gSystem->DirName(raw.Data());
	      // 		    glraw.NAME        = gSystem->BaseName(raw.Data());
	      // 		    glraw.BOOT_NUMBER = boot_number;
	      // 		    //
	      // 		    insertPamelaRawFile( &glraw );
	      // 		    //		    
	      // 		    id_raw = glraw.ID;		    
	      // 		}else{
	      // 		    row = result->Next();
	      // 		    id_raw = (UInt_t)atoll(row->GetField(0));
	      // 		}
	      // 		if ( IsDebug() ) cout << "ID_RAW = "<<id_raw<<endl;

	      // ---------------------------------------------------------------------
	      // step 1(bis): retrieve the timesync id associated to the file
	      // (NB, uso lo stesso associato al file iniziale)
	      // ---------------------------------------------------------------------
	      UInt_t idtimesync = 0;
	      oss.str("");
              oss << " SELECT ID FROM GL_TIMESYNC where TIMESYNC="<<chlastts<<" AND OBT0="<<chobtts*1000<<" and ID_RESURS_OFFSET="<< idresof <<" limit 1;"; // 10RED BUG!!!! without 'and ID_RESURS_OFFSET="<< idresof ' this query is not enough to ensure finding the correct line in GL_TIMSYNC...
	      if ( debug ) printf(" %s \n",oss.str().c_str());
	      result = conn->Query(oss.str().c_str());
	      if ( !result ) throw -3;
		row = result->Next();
		if ( !row ) throw -3;
		idtimesync = (UInt_t)atoll(row->GetField(0));
		if ( IsDebug() ) cout << "ID_TIMESYNC = "<<idtimesync<<endl;
		
		delete result;// mmm... "Error in <TMySQLResult::Next>: result set closed" solved? 090112 [8RED error messages]
		// ---------------------------------------------------------------------
		// step 2: insert a new root file in GL_ROOT
		// ---------------------------------------------------------------------
		//
		// check if the root file already exist
		//
		UInt_t id_root = 0;
		oss.str("");
		oss << "SELECT ID FROM GL_ROOT where NAME=\"" << gSystem->BaseName(name.Data()) <<"\";";
		if ( IsDebug() ) cout << oss.str().c_str() << endl;
		
		result = conn->Query(oss.str().c_str());
		if ( !result ) throw -4;;
		if ( IsDebug() ) cout <<"Rows: "<<result->GetRowCount()<<endl;
		if( result->GetRowCount() == 0){
		    if ( IsDebug() ) cout << " << Insert new ROOT file >> "<<endl;
		    // - - - - - - - - - - -
		    // insert new root file
		    // - - - - - - - - - - - 
		    GL_ROOT glroot = GL_ROOT();		    
		    glroot.ID_RAW      = id_raw;
		    glroot.ID_TIMESYNC = idtimesync;
		    //
		    // EM STATIC = the full expanded path must be put in the DB, KEEPENV = the path given as input (or found in ROOT_TABLE) must be used, 
		    //             NOT STATIC NOT KEEPENV = $PAM_L0 must be used in the DB
		    //
		    if ( STATIC ){
		      glroot.PATH        = (TString)gSystem->ExpandPathName(path);
		    } else {
		      if ( KEEPENV ){
			glroot.PATH      = path;
		      } else {
			glroot.PATH      = "$PAM_L0";
		      };
		    };
		    //		    glroot.PATH        = path; 
		    glroot.NAME        = name;
		    //
		    insertPamelaRootFile( &glroot );
		    //		    
		    id_root = glroot.ID;		    
		}else{
		    row = result->Next();
		    if(row)id_root = (UInt_t)atoll(row->GetField(0));
		}
		if ( IsDebug() ) cout << "ID_ROOT = "<<id_root<<endl;

		delete result;// mmm... "Error in <TMySQLResult::Next>: result set closed" solved? 090112 [8RED error messages]
		// ---------------------------------------------------------------------
		// step 3: modify time-tag of corrupted GL_TRK_CALIB entry
		// ---------------------------------------------------------------------
		if ( IsDebug() ) cout << " << Modify time-tag of calibration ID="<<id<<" >> "<<endl;
		oss.str("");
		oss << " UPDATE GL_TRK_CALIB SET "   
		    << " TO_TIME=0 , FROM_TIME=0  WHERE " 
		    << " ID = "<< id  << ";";
		if ( IsDebug() ) cout << oss.str().c_str() << endl;
		result = conn->Query(oss.str().c_str());
		if ( !result ) throw -4;;

		delete result; // mmm... "Error in <TMySQLResult::Next>: result set closed" solved? 090112 [8RED error messages]

		// ---------------------------------------------------------------------
		// step 4: insert the new calibration:
		// ---------------------------------------------------------------------
		if ( IsDebug() ) cout << " << Insert new TRK calibration >> "<<endl;
		//
		GL_TRK_CALIB glcal = GL_TRK_CALIB();	    
		//
		glcal.ID_ROOT_L0        = id_root;
		glcal.EV_ROOT_CALIBTRK1 = this_t1;
		glcal.EV_ROOT_CALIBTRK2 = this_t2;
		glcal.FROM_TIME         = fromtime;
		glcal.TO_TIME           = totime;
		glcal.OBT1              = obt1;
		glcal.OBT2              = obt2;
		glcal.PKT1              = pkt1;
		glcal.PKT2              = pkt1;
		glcal.BOOT_NUMBER       = GetBOOTnumber();
		glcal.VALIDATION        = this_valid;
		//
		HandleTRK_CALIB(&glcal);
		if ( IsDebug() ) cout << "ID = "<<glcal.ID<<endl;
		//
		
	    }
	    if ( IsDebug() ) cout << "------------------------------------------------------------" <<endl;

	}while(1);//end loop over calibrations
	
	
	if( rresult )delete rresult; // 10RED bug
	if( row    )delete row;
	
	

	


    }


// 	// ------------------------------
// 	// try to recover the calibration
// 	// ------------------------------
// 	cout << "TRY TO RECOVER TRACKER CALIBRATION"<<endl;
// 	//
// 	ULong64_t time  = 0; //absolute time
// 	string    path[100]; //mettere un limite massimo
// 	int       nrows = 0;
// 	UInt_t    pkt   = 0;
// 	UInt_t    obt   = 0;
// 	char     *type  = "";
// 	EventHeader *eh   = new EventHeader();
// 	CalibTrk1Event *c = new CalibTrk1Event();
	
//       //
//       if(which_is_not_valid==1 || which_is_not_valid==3){
// 	  //
// 	  cout << "PKT1 --> missing or corrupted "<<endl;
// 	  type = "CalibTrk1";
// 	  pkt  = pkt1;
// 	  obt  = obt1;
// 	  time = this->GetAbsTime(obt1);
// 	  if( pkt1 == 0 ){//missing
// 	      time = this->GetAbsTime(obt2); 
// 	      pkt  = pkt2-1;	      
// 	  }
// 	  //
//       }else if (which_is_not_valid==2 || which_is_not_valid==3){
// 	  //
// 	  cout << "PKT2--> missing or corrupted "<<endl;
// 	  type = "CalibTrk2 ";
// 	  pkt  = pkt2;
// 	  obt  = obt2;
// 	  time = this->GetAbsTime(obt2);
// 	  if( pkt2 == 0 ){//missing
// 	      time = this->GetAbsTime(obt1); 
// 	      pkt  = pkt1+1;	      
// 	  }
// 	  //
//       }else{
// 	  cout << "this should not happen!!! "<<endl;
// 	  trow -666;
//       }
      
//       nrows = Query_ROOT_TABLE(time,conn,path);// get the list of file which might contain the packet
      

//       for(int r=0; r<nrows; r++){ //loop over rows
// 	  if(path)cout << r << " >>>> "<<(path+r)->c_str() << endl;
// 	  /// verifica che il file non sia quello gia` aperto
//       }

//       ////////////////////////////////////////////////////////////////////////

//       TSQLResult *result = 0;
//       TSQLRow    *row    = 0;
//       //
//       stringstream oss;
//       oss.str("");
//       // ----------------------------------------
//       // read the id of last calibration inserted
//       // ----------------------------------------
//       oss.str("");
//       oss << " SELECT ";
//       oss << " (ID,ID_ROOT_L0,EV_ROOT_CALIBTRK1,EV_ROOT_CALIBTRK2,FROM_TIME,TO_TIME,OBT1,PKT1,OBT2,PKT2,BOOT_NUMBER,VALIDATION) ";
//       oss << " ORDER BY ID DESC LIMIT 1; ";
      
//       result = conn->Query(oss.str().c_str());
//       row = result->Next();
//       if( !row )throw -666;

//       if( result )delete result;
//       if( row    )delete row;

//       UInt_t id = (UInt_t)atoll(row->GetField(0));

//       // -------------------------------------
//       // ...and modify it with new parameters
//       // -------------------------------------
      

//   }
  //
  return(0);
};


/**
 * Scan S4 calibrations packets, fill the GL_S4_CALIB table
 */
Int_t PamelaDBOperations::insertS4_CALIB(){
  //
  TSQLResult *result = 0;
  TSQLRow    *row    = 0;
  //
  stringstream oss;
  oss.str("");
  //
  TTree *tr = 0;
  EventHeader *eh = 0;
  PscuHeader *ph = 0;
  //
  UInt_t nevents = 0;
  UInt_t fromtime = 0;
  UInt_t totime = 0;
  UInt_t obt = 0;
  UInt_t pkt = 0;
  //
  tr = (TTree*)file->Get("CalibS4");
  if ( !tr || tr->IsZombie() ) throw -24;
  //
  tr->SetBranchAddress("Header", &eh);
  //
  nevents = tr->GetEntries();
  //
  if ( !nevents ) return(1);
  //
  for (UInt_t i = 0; i < nevents; i++){
    //
    tr->GetEntry(i);
    //
    ph = eh->GetPscuHeader();
    obt = ph->GetOrbitalTime();  
    pkt = ph->GetCounter();  
    fromtime = this->GetAbsTime(ph->GetOrbitalTime());  
    if ( this->PKT(pkt) >= this->PKT(pktfirst) && this->PKT(pkt) <= upperpkt && this->OBT(obt) >= this->OBT(obtfirst) && this->OBT(obt) <= upperobt ){
      //    if ( this->PKT(pkt) >= this->PKT(pktfirst) && this->OBT(obt) >= this->OBT(obtfirst) ){
      //
      if ( IsDebug() ) printf(" S4 calibration at time %u obt %u pkt %u \n",fromtime,obt,pkt);
      //
      // check if the calibration has already been inserted
      //
      oss.str("");
      oss << " SELECT ID FROM GL_S4_CALIB WHERE "
	  << " BOOT_NUMBER = "<< this->GetBOOTnumber() << " AND "
	  << " OBT = "<< obt << " AND "
	  << " PKT = "<< pkt << ";";
      //
      if ( IsDebug() ) printf(" Check if the S4 calibration has already been inserted: query is \n %s \n",oss.str().c_str());
      result = conn->Query(oss.str().c_str());
      //
      if ( !result ) throw -4;
      //
      row = result->Next();
      //
      if ( row ){
	//
	if ( IsDebug() ) printf(" S4 calibration already inserted in the DB\n");
	if ( PEDANTIC ) throw -81;
	//
      } else {
	//
	// we have to insert a new calibration, check where to place it
	//
	oss.str("");
	oss << " SELECT ID,TO_TIME FROM GL_S4_CALIB WHERE "
	    << " FROM_TIME < "<< fromtime << " AND "
	    << " TO_TIME > "<< fromtime << ";";
	//
	if ( IsDebug() ) printf(" Check where to place the S4 calibration: query is \n %s \n",oss.str().c_str());
	result = conn->Query(oss.str().c_str());
	//
	if ( !result ) throw -4;
	//
	row = result->Next();
	//
	if ( !row ){
	  //
	  // no calibrations in the db contain our calibration
	  //
	  if ( IsDebug() ) printf(" Calibration with fromtime lower than others to be inserted in the DB \n");
	  if ( fromtime < 1150871000 ){  
	    if ( IsDebug() ) printf(" First PAMELA flight calibration at time %u \n",fromtime);
	    fromtime = 0;// the first flight calibration was taken at about  1156429100 s, this line allow to analyze first runs in raw mode
	  };
	  //
	  oss.str("");
	  oss << " SELECT FROM_TIME FROM GL_S4_CALIB WHERE "
	      << " FROM_TIME > "<< fromtime << " ORDER BY FROM_TIME ASC LIMIT 1;";
	  //
	  if ( IsDebug() ) printf(" Check the upper limit for calibration: query is \n %s \n",oss.str().c_str());
	  result = conn->Query(oss.str().c_str());
	  //
	  if ( !result ) throw -4;
	  //
	  row = result->Next();
	  if ( !row ){
	    totime = numeric_limits<UInt_t>::max();
	  } else {
	    totime = (UInt_t)atoll(row->GetField(0));
	  };
	  //
	} else {
	  //
	  // determine upper and lower limits and make space for the new calibration
	  //
	  totime = (UInt_t)atoll(row->GetField(1));
	  //
	  oss.str("");
	  oss << " UPDATE GL_S4_CALIB SET "   
	      << " TO_TIME = "<< fromtime << " WHERE "  // NOTICE: to_time is equal to from_time of the calibration before, so the interval is: [from_time,to_time[
	      << " ID = "<< row->GetField(0) << ";";
	  //
	  if ( IsDebug() ) printf(" Make space for the new calibration: query is \n %s \n",oss.str().c_str());
	  result = conn->Query(oss.str().c_str());
	  //
	  if ( !result ) throw -4;
	  //
	};
	//
	oss.str("");
	oss << " INSERT INTO GL_S4_CALIB (ID,ID_ROOT_L0,EV_ROOT,FROM_TIME,TO_TIME,OBT,PKT,BOOT_NUMBER) "
	    << " VALUES (NULL,' "
	    << idroot << "','"
	    << i << "','"
	    << fromtime << "','"
	    << totime << "','"
	    << obt << "','"
	    << pkt << "','"
	    << this->GetBOOTnumber() << "');";
	//
	if ( IsDebug() ) printf(" Insert the new calibration: query is \n %s \n",oss.str().c_str());
	//
	result = conn->Query(oss.str().c_str());
	//
	if ( !result ) throw -4;
	//
      };
      //
    } else {
      //
      if ( IsDebug() ) printf(" S4 calibration at time %u obt %u pkt %u OUTSIDE the considered time interval\n",fromtime,obt,pkt);
      //      if ( PEDANTIC ) throw -82;
      //
    };      
    //      
  };
  //
  return(0);
};
 
/**
 * Scan the fragment table and move old fragments to the GL_RUN table
 */
Int_t PamelaDBOperations::CleanGL_RUN_FRAGMENTS(){
  return(this->CleanGL_RUN_FRAGMENTS(""));
};

/**
 * Scan the fragment table and move old fragments to the GL_RUN table
 */
Int_t PamelaDBOperations::CleanGL_RUN_FRAGMENTS(Bool_t runpieces){
  return(this->CleanGL_RUN_FRAGMENTS("",runpieces));
};

/**
 * Scan the fragment table and move old fragments to the GL_RUN table
 */
Int_t PamelaDBOperations::CleanGL_RUN_FRAGMENTS(TString fcleanfile){
  return(this->CleanGL_RUN_FRAGMENTS("",false));
};

/**
 * Scan the fragment table and move old fragments to the GL_RUN table
 */
Int_t PamelaDBOperations::CleanGL_RUN_FRAGMENTS(TString fcleanfile, Bool_t runpieces){
  //
  TSQLResult *nresult = 0;
  TSQLRow    *nrow    = 0;
  TSQLResult *nresult1 = 0;
  TSQLRow    *nrow1    = 0;
  TSQLResult *result = 0;
  TSQLRow    *row    = 0;
  TSQLResult *result2 = 0;
  TSQLRow    *row2   = 0;
  //
  UInt_t moved = 0;
  //
  stringstream oss;
  oss.str("");
  //
  // Before moving blindly the runs from GL_RUN_FRAGMENTS to GL_RUN try to find out if we have runs divided in more than two pieces (chewbacca or explicit flag only)
  //
  if ( runpieces ){
    //
    UInt_t nid = 0;
    UInt_t myid[500];
    memset(myid,0,500*sizeof(UInt_t));
    //
    oss.str("");
    oss << "SELECT ID,RUNTRAILER_TIME,RUNTRAILER_PKT,BOOT_NUMBER FROM GL_RUN_FRAGMENTS WHERE INSERT_TIME <= '" << clean_time->AsSQLString() << "' order BY RUNHEADER_TIME asc;";
    if ( IsDebug() ) printf(" Select from GL_RUN_FRAGMENTS runs older than %s : query is \n %s \n",clean_time->AsSQLString(),oss.str().c_str());
    nresult = conn->Query(oss.str().c_str());
    //
    if ( nresult ){
      //
      nrow = nresult->Next();
      //
      while ( nrow ){    
	//
	UInt_t mbo = (UInt_t)atoll(nrow->GetField(3));
	UInt_t mrhp = (UInt_t)atoll(nrow->GetField(2));
	UInt_t mrht = (UInt_t)atoll(nrow->GetField(1));
	Bool_t anr = true;
	Bool_t runisthere = true;
	//
	for (UInt_t u=0; u<=nid; u++){
	  if ( (UInt_t)atoll(nrow->GetField(0)) == myid[u] && (UInt_t)atoll(nrow->GetField(0)) != 0 ) runisthere = false;
	};
	//
	// check if the run is still in the fragment table or if we have just move it in the gl_run table!
	//
	if ( runisthere ){
	  //
	  memset(myid,0,500*sizeof(UInt_t));
	  nid = 0;
	  myid[nid] = (UInt_t)atoll(nrow->GetField(0));
	  //
	  while ( anr ){
	    //
	    oss.str("");
	    oss << "SELECT ID,RUNTRAILER_TIME,RUNTRAILER_PKT,BOOT_NUMBER FROM GL_RUN_FRAGMENTS WHERE BOOT_NUMBER=" << mbo << " AND RUNHEADER_PKT=" << mrhp <<  "+1 AND ABS(RUNHEADER_TIME-"<< (float)mrht <<")<=1 AND INSERT_TIME <= '" << clean_time->AsSQLString() << "' order BY RUNHEADER_TIME asc;"; // 10RED MYSQL OPERATOR BUG
	    if ( IsDebug() ) printf(" In the loop searching for fragmented runs : query is \n %s \n",oss.str().c_str());
	    //
	    nresult1 = conn->Query(oss.str().c_str());
	    //
	    if ( nresult1 ){
	      //
	      if ( nresult1->GetRowCount() == 1 ){    
		//
		// one piece is found
		//
		nrow1 = nresult1->Next();
		//
		if ( nrow1 ){
		  //
		  nid++;
		  myid[nid] = (UInt_t)atoll(nrow1->GetField(0));
		  mbo = (UInt_t)atoll(nrow1->GetField(3));
		  mrhp = (UInt_t)atoll(nrow1->GetField(2));
		  mrht = (UInt_t)atoll(nrow1->GetField(1));
		  if ( debug ) printf(" FOUND A PIECE OF RUN! nid %u myid[nid] %u mbo %u mrhp %u mrht %u \n",nid,myid[nid],mbo,mrhp,mrht);
		  //
		  nrow1->Close();
		} else {
		  throw -88;
		};
	      } else {
		anr = false;
	      };
	      nresult1->Close();
	    } else {
	      throw -88;
	    };
	  };
	  //
	  // handle these runs which are ordered and "good". Does the first contain a valid runheader?
	  //
	  oss.str("");
	  oss << " ID= "<< myid[0];
	  //
	  glrun->Query_GL_RUN_FRAGMENTS(oss.str().c_str(),conn);
	  //
	  if ( glrun->GetACQ_BUILD_INFO() != 0 ){
	    //
	    // the first piece contains a good runheader we can update all the other runs with correct infos!
	    //
	    for (UInt_t u=1; u <= nid ; u++){
	      oss.str("");
	      oss << "UPDATE GL_RUN_FRAGMENTS SET "
		  << " RUNHEADER_TIME=" << glrun->GetRUNHEADER_TIME()<< " , "
		  << " RUNHEADER_OBT=" << glrun->GetRUNHEADER_OBT()<< " , "
		  << " RUNHEADER_PKT=" << glrun->GetRUNHEADER_PKT()<< " , "
		  << " COMPILATIONTIMESTAMP=" << glrun->GetCOMPILATIONTIMESTAMP()<< " , "
		  << " FAV_WRK_SCHEDULE=" << glrun->GetFAV_WRK_SCHEDULE()<< " , "
		  << " EFF_WRK_SCHEDULE=" << glrun->GetEFF_WRK_SCHEDULE()<< " , "
		  << " PRH_VAR_TRG_MODE_A=" << glrun->GetPRH_VAR_TRG_MODE_A()<< " , "
		  << " PRH_VAR_TRG_MODE_B=" << glrun->GetPRH_VAR_TRG_MODE_B()<< " , "
		  << " ACQ_BUILD_INFO=" << glrun->GetACQ_BUILD_INFO()<< " , "
		  << " ACQ_VAR_INFO=" << glrun->GetACQ_VAR_INFO()<< " , "
		  << " RM_ACQ_AFTER_CALIB=" << glrun->GetRM_ACQ_AFTER_CALIB()<< " , "  
		  << " RM_ACQ_SETTING_MODE=" << glrun->GetRM_ACQ_SETTING_MODE()<< " , "  
		  << " TRK_CALIB_USED=" << glrun->GetTRK_CALIB_USED()<< " , "  
		  << " CAL_DSP_MASK=" << glrun->GetCAL_DSP_MASK()<< " , "  
		  << " LAST_TIMESYNC=" << glrun->GetLAST_TIMESYNC()<< " , ";
	      //
	      if ( glrun->GetPHYSENDRUN_MASK_S3S2S12() )
		oss << " PHYSENDRUN_MASK_S3S2S12=" << glrun->GetPHYSENDRUN_MASK_S3S2S12() << " , "; 
	      if ( glrun->GetPHYSENDRUN_MASK_S11CRC() )
		oss << " PHYSENDRUN_MASK_S11CRC=" << glrun->GetPHYSENDRUN_MASK_S11CRC() << " , ";
	      //	      
	      oss << " OBT_TIMESYNC=" << glrun->GetOBT_TIMESYNC();
	      oss << " WHERE ID=" << myid[u] << ";";
	      conn->Query(oss.str().c_str());	
	    };
	    //
	  } else {
	    //
	    // sig no runheader, let set anyway what is possible...
	    //
	    for (UInt_t u=1; u <= nid ; u++){
	      oss.str("");
	      oss << "UPDATE GL_RUN_FRAGMENTS SET "
		  << " RUNHEADER_TIME=" << glrun->GetRUNHEADER_TIME()<< " , ";
	      //
	      if ( glrun->GetPHYSENDRUN_MASK_S3S2S12() )
		oss << " PHYSENDRUN_MASK_S3S2S12=" << glrun->GetPHYSENDRUN_MASK_S3S2S12()<< " , ";
	      if ( glrun->GetPHYSENDRUN_MASK_S11CRC() )
		oss << " PHYSENDRUN_MASK_S11CRC=" << glrun->GetPHYSENDRUN_MASK_S11CRC()<< " , "; 
	      //	      
	      oss << " RUNHEADER_OBT=" << glrun->GetRUNHEADER_OBT()<< " , "
		  << " RUNHEADER_PKT=" << glrun->GetRUNHEADER_PKT();
	      oss << " WHERE ID=" << myid[u] << ";"; // BUG!!! 090112
	      conn->Query(oss.str().c_str());	
	    };	  
	  };
	  //
	  // now let's look for runtrailer if any in the last run
	  //
	  oss.str("");
	  oss << " ID= "<< myid[nid];
	  //
	  glrun->Query_GL_RUN_FRAGMENTS(oss.str().c_str(),conn);
	  //
	  if ( glrun->GetPKT_READY_COUNTER() != 0 ){
	    //
	    // the first piece contains a good runtrailer we can update all the other runs with correct infos!
	    //
	    for (UInt_t u=0; u < nid ; u++){
	      oss.str("");
	      oss << "UPDATE GL_RUN_FRAGMENTS SET "
		  << " RUNTRAILER_TIME=" << glrun->GetRUNTRAILER_TIME()<< " , "
		  << " RUNTRAILER_OBT=" << glrun->GetRUNTRAILER_OBT()<< " , "
		  << " RUNTRAILER_PKT=" << glrun->GetRUNTRAILER_PKT()<< " , "
		  << " PKT_COUNTER=" << glrun->GetPKT_COUNTER()<< " , ";
	      //
	      if ( glrun->GetPHYSENDRUN_MASK_S3S2S12() ){
		oss << " PHYSENDRUN_MASK_S3S2S12=" << glrun->GetPHYSENDRUN_MASK_S3S2S12()<< " , "; };
	      if ( glrun->GetPHYSENDRUN_MASK_S11CRC() ) {
		oss << " PHYSENDRUN_MASK_S11CRC=" << glrun->GetPHYSENDRUN_MASK_S11CRC()<< " , "; };
	      //	      
	      oss << " PKT_READY_COUNTER=" << glrun->GetPKT_READY_COUNTER()
		  << " WHERE ID=" << myid[u] << ";";
	      conn->Query(oss.str().c_str());	
	    };
	    //
	  } else {
	    //
	    // sig no runtrailer, let set anyway what is possible...
	    //
	    for (UInt_t u=0; u < nid ; u++){
	      oss.str("");
	      oss << "UPDATE GL_RUN_FRAGMENTS SET "
		  << " RUNTRAILER_TIME=" << glrun->GetRUNTRAILER_TIME()<< " , "
		  << " RUNTRAILER_OBT=" << glrun->GetRUNTRAILER_OBT()<< " , ";
	      //
	      if ( glrun->GetPHYSENDRUN_MASK_S3S2S12() ){
		oss << " PHYSENDRUN_MASK_S3S2S12=" << glrun->GetPHYSENDRUN_MASK_S3S2S12()<< " , "; };
	      if ( glrun->GetPHYSENDRUN_MASK_S11CRC() ){
		oss << " PHYSENDRUN_MASK_S11CRC=" << glrun->GetPHYSENDRUN_MASK_S11CRC()<< " , "; };
	      //	      
	      oss << " RUNTRAILER_PKT=" << glrun->GetRUNTRAILER_PKT();
	      oss << " WHERE ID=" << myid[u] << ";"; // BUG!!! 090112
	      conn->Query(oss.str().c_str());	
	    };	  
	  };
	  //
	  // Now we want to cross indexize the runs
	  //
	  for (UInt_t u=0; u < nid ; u++){
	    oss.str("");
	    oss << "UPDATE GL_RUN_FRAGMENTS SET "
		<< " ID_RUN_FRAG=" << myid[u+1] << " where ID=" << myid[u] <<";";
	    conn->Query(oss.str().c_str());	
	  };	
	  oss.str("");
	  oss << "UPDATE GL_RUN_FRAGMENTS SET "
	      << " ID_RUN_FRAG=" << myid[0] << " where ID=" << myid[nid] <<";";
	  conn->Query(oss.str().c_str());		
	  //
	  // and now we can move the runs in the GL_RUN table
	  //
	  for (UInt_t u=0; u <= nid; u++){
	    oss.str("");
	    oss << " ID= "<< myid[u];
	    //
	    glrun->Query_GL_RUN_FRAGMENTS(oss.str().c_str(),conn);   
	    //
	    if ( u == 0 ){
	      oss.str("");
	      oss << " SELECT ID,NEVENTS,TRK_CALIB_USED,PKT_COUNTER FROM GL_RUN WHERE "
		  << " BOOT_NUMBER=" << glrun->GetBOOT_NUMBER() << " AND ("
		  << " (RUNHEADER_TIME>=" << (UInt_t)(glrun->GetRUNHEADER_TIME()-10) << " AND "
		  << " RUNTRAILER_TIME<=" << (UInt_t)(glrun->GetRUNTRAILER_TIME()+10) << " AND ("
		  << " RUNHEADER_OBT>=" << glrun->GetRUNHEADER_OBT() << " OR "
		  << " RUNHEADER_PKT>=" << glrun->GetRUNHEADER_PKT() << ") AND ("
		  << " RUNTRAILER_OBT<=" << glrun->GetRUNTRAILER_OBT() << " OR "
		  << " RUNTRAILER_PKT<=" << glrun->GetRUNTRAILER_PKT() << ") ) OR "
		  << " (RUNHEADER_TIME<=" << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "
		  << " RUNTRAILER_TIME>=" << (UInt_t)glrun->GetRUNTRAILER_TIME() <<" AND ("
		  << " RUNHEADER_OBT<=" << glrun->GetRUNHEADER_OBT() << " OR "
		  << " RUNHEADER_PKT<=" << glrun->GetRUNHEADER_PKT() << ") AND ("
		  << " RUNTRAILER_OBT>=" << glrun->GetRUNTRAILER_OBT() << " OR "
		  << " RUNTRAILER_PKT>=" << glrun->GetRUNTRAILER_PKT() << ") ));";
	      //
	      if ( IsDebug() ) printf(" check if run has been inserted: query is \n %s \n",oss.str().c_str());
	      result2 = conn->Query(oss.str().c_str());
	      //
	      if ( !result2 ) throw -4;
	      //
	      row2 = result2->Next();
	      //
	      if ( row2 ){
		if ( IsDebug() ) printf(" The run already exists in the GL_RUN table! \n");
		if ( PEDANTIC ) throw -83;
		row2->Close();
	      };
	      result2->Close();
	    };
	    //
	    if ( IsDebug() ) printf(" The run is new \n");
	    if ( IsDebug() ) printf(" -> fill the DB \n");      
	    //
	    glrun->Fill_GL_RUN(conn);   
	    //	  
	    if ( IsDebug() ) printf(" Delete run %u from the GL_RUN_FRAGMENTS table \n",myid[u]);      
	    //
	    glrun->DeleteRun(conn,myid[u],"GL_RUN_FRAGMENTS");	      
	    //
	    moved++;
	    //
	  };
	  //
	};
	//
	nrow = nresult->Next();
      };
    };



  };
  //
  if ( !strcmp(fcleanfile.Data(),"") ){
    //
    // check if there are entries older than "olderthan" seconds from now
    //
    oss.str("");
    oss << " SELECT ID FROM GL_RUN_FRAGMENTS WHERE"
	<< " INSERT_TIME <= '" << clean_time->AsSQLString() << "';";
    //
    if ( IsDebug() ) printf(" Select from GL_RUN_FRAGMENTS runs older than %s : query is \n %s \n",clean_time->AsSQLString(),oss.str().c_str());
    result = conn->Query(oss.str().c_str());
    //
  } else {
    oss.str("");
    oss << " SELECT ID FROM GL_ROOT WHERE NAME='" << fcleanfile.Data() << "';";
    if ( IsDebug() ) printf(" Getting ID_ROOT_L0 query %s \n",oss.str().c_str());
    result = conn->Query(oss.str().c_str());
    //    
    if ( result ){
      //
      row = result->Next();
      //
      if ( row ){
	oss.str("");
	oss << " SELECT ID FROM GL_RUN_FRAGMENTS WHERE"
	    << " ID_ROOT_L0=" << row->GetField(0) << ";";
	//
	if ( IsDebug() ) printf(" Select from GL_RUN_FRAGMENTS for ROOT file query is \n %s \n",oss.str().c_str());
	result = conn->Query(oss.str().c_str());
	//    
      };
    } else {
      return(2);
    };
  };
  //
  if ( result ){
    //
    row = result->Next();
    //
    while ( row ){
      //
      oss.str("");
      oss << " ID= "<< row->GetField(0);
      //
      glrun->Query_GL_RUN_FRAGMENTS(oss.str().c_str(),conn);   
      //
      oss.str("");
      oss << " SELECT ID,NEVENTS,TRK_CALIB_USED,PKT_COUNTER,ID_ROOT_L0 FROM GL_RUN WHERE "
	  << " BOOT_NUMBER=" << glrun->GetBOOT_NUMBER() << " AND ("
	  << " (RUNHEADER_TIME>=" << (UInt_t)(glrun->GetRUNHEADER_TIME()-10) << " AND "
	  << " RUNTRAILER_TIME<=" << (UInt_t)(glrun->GetRUNTRAILER_TIME()+10) << " AND ("
	  << " RUNHEADER_OBT>=" << glrun->GetRUNHEADER_OBT() << " OR "
	  << " RUNHEADER_PKT>=" << glrun->GetRUNHEADER_PKT() << ") AND ("
	  << " RUNTRAILER_OBT<=" << glrun->GetRUNTRAILER_OBT() << " OR "
	  << " RUNTRAILER_PKT<=" << glrun->GetRUNTRAILER_PKT() << ") ) OR "
	  << " (RUNHEADER_TIME<=" << (UInt_t)glrun->GetRUNHEADER_TIME() << " AND "
	  << " RUNTRAILER_TIME>=" << (UInt_t)glrun->GetRUNTRAILER_TIME() <<" AND ("
	  << " RUNHEADER_OBT<=" << glrun->GetRUNHEADER_OBT() << " OR "
	  << " RUNHEADER_PKT<=" << glrun->GetRUNHEADER_PKT() << ") AND ("
	  << " RUNTRAILER_OBT>=" << glrun->GetRUNTRAILER_OBT() << " OR "
	  << " RUNTRAILER_PKT>=" << glrun->GetRUNTRAILER_PKT() << ") ));";
      //
      if ( IsDebug() ) printf(" check if run has been inserted: query is \n %s \n",oss.str().c_str());
      result2 = conn->Query(oss.str().c_str());
      //
      if ( !result2 ) throw -4;
      //
      row2 = result2->Next();
      //
      if ( !row2 ){
	//
	if ( IsDebug() ) printf(" The run is new \n");
	if ( IsDebug() ) printf(" -> fill the DB \n");      
	//
	//	glrun->SetID(this->AssignRunID()); we use the old run number!
	glrun->SetID_RUN_FRAG(glrun->GetID());
	glrun->Fill_GL_RUN(conn);   
	//
	// 	oss.str("");
	// 	oss << " SELECT ID FROM GL_RUN WHERE "
	// 	    << " BOOT_NUMBER=" << glrun->GetBOOT_NUMBER() << " AND "
	// 	    << " RUNHEADER_PKT=" << (UInt_t)glrun->GetRUNHEADER_PKT() << " AND "
	// 	    << " RUNTRAILER_PKT=" << (UInt_t)glrun->GetRUNTRAILER_PKT() << " AND "
	// 	    << " RUNHEADER_OBT=" << (UInt_t)glrun->GetRUNHEADER_OBT() << " AND "
	// 	    << " RUNTRAILER_OBT=" << (UInt_t)glrun->GetRUNTRAILER_OBT() << "; ";
	// 	//
	// 	if ( IsDebug() ) printf(" Look for the ID of the inserted run: query is \n %s \n",oss.str().c_str());
	// 	result2 = conn->Query(oss.str().c_str());
	// 	//
	// 	if ( !result2 ) throw -4;
	// 	//
	// 	row2 = result2->Next();
	// 	//
	// 	if ( !row2 ) throw -25;
	// 	//
	// 	oss.str("");
	// 	oss << " UPDATE GL_RUN SET ID_RUN_FRAG = " << row2->GetField(0) << " WHERE ID = " << row2->GetField(0);
	// 	if ( IsDebug() ) printf(" Update the ID_RUN_FRAG of the inserted run: query is \n %s \n",oss.str().c_str());
	// 	result2 = conn->Query(oss.str().c_str());
	// 	//
	// 	if ( !result2 ) throw -4;
	//
	moved++;
	//
      } else {

	// questa parte mah mah mah... da controllare

	//
	// we end up here if chewbacca and we have RH---| small gap |---RT, in this case the two pieces are attached and moved to GL_RUN. We are now processing the 
	// "small gap" piece... we recognize this since: we have two entries from this query, the pkt number is consistent with our pkt number.
	//
	// 090112 [8RED (-70): RUN ALREADY INSERTED]
	//
	Bool_t OK = false;
	UInt_t IDRL2A = 0;
	UInt_t IDRL2B = 0;
	  if ( result2->GetRowCount() == 2 ){
	    IDRL2A = (UInt_t)atoll(row2->GetField(0));
	    UInt_t IDRL0A = (UInt_t)atoll(row2->GetField(4));
	    row2 = result2->Next();
	    IDRL2B = (UInt_t)atoll(row2->GetField(0));
	    UInt_t IDRL0B = (UInt_t)atoll(row2->GetField(4));
	    if ( IsDebug() ) printf(" IDRL0A %u B %u IDRL2A %u B %u \n",IDRL0A,IDRL0B,IDRL2A,IDRL2B);
	    //	    if ( IDRL0A == IDRL0B ){
// 	      TSQLResult *result2a = 0;
// 	      TSQLRow    *row2a    = 0;
// 	      oss.str("");
// 	      oss << "select PKT_NUMBER_FINAL from ROOT_TABLE_MERGING where REAL_TIME_INIT<" << chrtinit << " order by REAL_TIME_INIT desc limit 1;";
// 	      if ( IsDebug() ) printf(" Check if we are in the case RH---| small gap |---RT: query is \n %s \n",oss.str().c_str());
// 	      result2a = conn->Query(oss.str().c_str());
// 	      //
// 	      if ( !result2a ) throw -4;
// 	      //
// 	      row2a = result2a->Next();
// 	      //
// 	      if ( row2a ){
// 		UInt_t PKA = (UInt_t)atoll(row2a->GetField(0));
// 		delete result2a;
// 		oss.str("");
// 		oss << "select PKT_NUMBER_INIT from ROOT_TABLE_MERGING where REAL_TIME_INIT>" << chrtinit << " order by REAL_TIME_INIT asc limit 1;";
// 		if ( IsDebug() ) printf(" Check if we are in the case RH---| small gap |---RT: query is \n %s \n",oss.str().c_str());
// 		result2a = conn->Query(oss.str().c_str());
// 		//
// 		if ( !result2a ) throw -4;
// 		//
// 		row2a = result2a->Next();
// 		//
// 		if ( row2a ){
// 		  UInt_t PKB = (UInt_t)atoll(row2a->GetField(0));
// 		  //
// 		  if ( IsDebug() ) printf(" PKT(PKA) + 1 %llu == runheaderpkt %llu && PKB = runtrailer %llu + 1 %llu \n",PKT(PKA)+1LL, PKT(glrun->GetRUNHEADER_PKT()),PKT(PKB), PKT(glrun->GetRUNTRAILER_PKT())+1LL);
// 		  if ( PKT(PKA)+1LL == PKT(glrun->GetRUNHEADER_PKT()) && PKT(PKB) == PKT(glrun->GetRUNTRAILER_PKT())+1LL ){
// 		    if ( IsDebug() ) printf(" Ok, we are in the case: RH---| small gap |---RT \n");
		    OK = true;
		    //		  };
		    //		};
		    //	      };		  
		    //	  };
	  };	  
	if ( OK ){
	  //
	  // this is the case in which we must insert a piece of run between two fragments in the GL_RUN table
	  //
	  // we have to update with runheader/trailer infos our run and we have to change the ROOT_ID_FRAG of the header piece ( 1/2 2/1 must become 1/3 3/2 2/1 )
	  //
	  GL_RUN *glA = new GL_RUN();
	  glA->Query_GL_RUN(IDRL2A,conn);
	  //
	  if ( glA->GetACQ_BUILD_INFO() != 0 ){
	    //
	    // the first piece contains a good runheader we can update all the other runs with correct infos!
	    //
	    oss.str("");
	    oss << "UPDATE GL_RUN_FRAGMENTS SET "
		<< " RUNHEADER_TIME=" << glA->GetRUNHEADER_TIME()<< " , "
		<< " RUNHEADER_OBT=" << glA->GetRUNHEADER_OBT()<< " , "
		<< " RUNHEADER_PKT=" << glA->GetRUNHEADER_PKT()<< " , "
		<< " COMPILATIONTIMESTAMP=" << glA->GetCOMPILATIONTIMESTAMP()<< " , "
		<< " FAV_WRK_SCHEDULE=" << glA->GetFAV_WRK_SCHEDULE()<< " , "
		<< " EFF_WRK_SCHEDULE=" << glA->GetEFF_WRK_SCHEDULE()<< " , "
		<< " PRH_VAR_TRG_MODE_A=" << glA->GetPRH_VAR_TRG_MODE_A()<< " , "
		<< " PRH_VAR_TRG_MODE_B=" << glA->GetPRH_VAR_TRG_MODE_B()<< " , "
		<< " ACQ_BUILD_INFO=" << glA->GetACQ_BUILD_INFO()<< " , "
		<< " ACQ_VAR_INFO=" << glA->GetACQ_VAR_INFO()<< " , "
		<< " RM_ACQ_AFTER_CALIB=" << glA->GetRM_ACQ_AFTER_CALIB()<< " , "  
		<< " RM_ACQ_SETTING_MODE=" << glA->GetRM_ACQ_SETTING_MODE()<< " , "  
		<< " TRK_CALIB_USED=" << glA->GetTRK_CALIB_USED()<< " , "  
		<< " CAL_DSP_MASK=" << glA->GetCAL_DSP_MASK()<< " , "  
		<< " LAST_TIMESYNC=" << glA->GetLAST_TIMESYNC()<< " , ";
	    //
	    if ( glA->GetPHYSENDRUN_MASK_S3S2S12() )
	      oss << " PHYSENDRUN_MASK_S3S2S12=" << glA->GetPHYSENDRUN_MASK_S3S2S12() << " , "; 
	    if ( glA->GetPHYSENDRUN_MASK_S11CRC() )
	      oss << " PHYSENDRUN_MASK_S11CRC=" << glA->GetPHYSENDRUN_MASK_S11CRC() << " , ";
	    //	      
	    oss << " OBT_TIMESYNC=" << glA->GetOBT_TIMESYNC();
	    oss << " WHERE ID=" << glrun->GetID() << ";";
	    if ( IsDebug() ) printf(" update with correct infos: %s\n",oss.str().c_str());
	    conn->Query(oss.str().c_str());	
	    //
	  } else {
	    //
	    // sig no runheader, let set anyway what is possible...
	    //
	    oss.str("");
	    oss << "UPDATE GL_RUN_FRAGMENTS SET "
		<< " RUNHEADER_TIME=" << glA->GetRUNHEADER_TIME()<< " , ";
	    //
	    if ( glA->GetPHYSENDRUN_MASK_S3S2S12() )
	      oss << " PHYSENDRUN_MASK_S3S2S12=" << glA->GetPHYSENDRUN_MASK_S3S2S12()<< " , ";
	    if ( glA->GetPHYSENDRUN_MASK_S11CRC() )
	      oss << " PHYSENDRUN_MASK_S11CRC=" << glA->GetPHYSENDRUN_MASK_S11CRC()<< " , "; 
	    //	      
	    oss << " RUNHEADER_OBT=" << glA->GetRUNHEADER_OBT()<< " , "
		<< " RUNHEADER_PKT=" << glA->GetRUNHEADER_PKT();
	    oss << " WHERE ID=" << glrun->GetID() << ";";
	    if ( IsDebug() ) printf(" update with correct infos2: %s\n",oss.str().c_str());
	    conn->Query(oss.str().c_str());	
	  };
	  //
	  // update runheader ROOT_ID_FRAG
	  //
	  oss.str("");
	  oss << "UPDATE GL_RUN SET ID_RUN_FRAG = " << glrun->GetID() << " where ID = " << IDRL2A << ";";
	  if ( IsDebug() ) printf(" update gl_run to have cross indexing: %s\n",oss.str().c_str());
	  conn->Query(oss.str().c_str());
	  //
	  // now let's look for runtrailer if any in the last run
	  //
	  glA->Query_GL_RUN(IDRL2B,conn);
	  //
	  if ( glA->GetPKT_READY_COUNTER() != 0 ){
	    //
	    // the first piece contains a good runtrailer we can update all the other runs with correct infos!
	    //
	    oss.str("");
	    oss << "UPDATE GL_RUN_FRAGMENTS SET "
		<< " RUNTRAILER_TIME=" << glA->GetRUNTRAILER_TIME()<< " , "
		<< " RUNTRAILER_OBT=" << glA->GetRUNTRAILER_OBT()<< " , "
		<< " RUNTRAILER_PKT=" << glA->GetRUNTRAILER_PKT()<< " , "
		<< " PKT_COUNTER=" << glA->GetPKT_COUNTER()<< " , ";
	    //
	    if ( glA->GetPHYSENDRUN_MASK_S3S2S12() ){
	      oss << " PHYSENDRUN_MASK_S3S2S12=" << glA->GetPHYSENDRUN_MASK_S3S2S12()<< " , "; };
	    if ( glA->GetPHYSENDRUN_MASK_S11CRC() ) {
	      oss << " PHYSENDRUN_MASK_S11CRC=" << glA->GetPHYSENDRUN_MASK_S11CRC()<< " , "; };
	    //	      
	    oss << " PKT_READY_COUNTER=" << glA->GetPKT_READY_COUNTER()
		<< " WHERE ID=" << glrun->GetID() << ";";
	    if ( IsDebug() ) printf(" update with correct trailer infos: %s\n",oss.str().c_str());
	    conn->Query(oss.str().c_str());	
	    //
	  } else {
	    //
	    // sig no runtrailer, let set anyway what is possible...
	    //
	    oss.str("");
	    oss << "UPDATE GL_RUN_FRAGMENTS SET "
		<< " RUNTRAILER_TIME=" << glA->GetRUNTRAILER_TIME()<< " , "
		<< " RUNTRAILER_OBT=" << glA->GetRUNTRAILER_OBT()<< " , ";
	      //
	    if ( glA->GetPHYSENDRUN_MASK_S3S2S12() ){
	      oss << " PHYSENDRUN_MASK_S3S2S12=" << glA->GetPHYSENDRUN_MASK_S3S2S12()<< " , "; };
	    if ( glA->GetPHYSENDRUN_MASK_S11CRC() ){
	      oss << " PHYSENDRUN_MASK_S11CRC=" << glA->GetPHYSENDRUN_MASK_S11CRC()<< " , "; };
	    //	      
	    oss << " RUNTRAILER_PKT=" << glrun->GetRUNTRAILER_PKT()
		<< " WHERE ID=" << glrun->GetID() << ";";
	    if ( IsDebug() ) printf(" update with correct trailer infos2: %s\n",oss.str().c_str());
	    conn->Query(oss.str().c_str());	
	  };
	  //
	  UInt_t myi = glrun->GetID();
	  oss.str("");
	  oss << " ID= "<< myi;
	  //
	  glrun->Query_GL_RUN_FRAGMENTS(oss.str().c_str(),conn);   
	  //
	  // fill the new run in GL_RUN
	  //
	  glrun->SetID_RUN_FRAG(IDRL2B);
	  glrun->Fill_GL_RUN(conn);	
	  glrun->DeleteRun(conn,0,"GL_RUN_FRAGMENTS");
	  delete glA;
	  moved++;
	  //
	} else {
	  //
	  // is just a repetition
	  //
	  if ( IsDebug() ) printf(" The run %u is already present in the GL_RUN table...\n",glrun->GetID());	
	  //	  printf(" CCCCCCCCICCCCCCCCCCCCIOOOOOOOOOO si muove Ciccio! %u \n",glrun->GetID());
	  //	  if ( PEDANTIC && glrun->GetID() != 61563 ) throw -83; 
	  if ( PEDANTIC ) throw -83; 
	};
	//	if ( IsDebug() ) printf(" The run already exists in the GL_RUN table! ...\n");
	//	if ( PEDANTIC ) throw -83;
      };
      if ( IsDebug() ) printf(" Delete run %s from the GL_RUN_FRAGMENTS table \n",row->GetField(0));      
      //
      //
      glrun->DeleteRun(conn,(UInt_t)atoll(row->GetField(0)),"GL_RUN_FRAGMENTS");
      //      oss.str("");
      //       oss << " DELETE from GL_RUN_FRAGMENTS where ID = " << row->GetField(0);
      //       if ( IsDebug() ) printf(" Clean the GL_RUN_FRAGMENTS table: query is \n %s \n",oss.str().c_str());
      //       result2 = conn->Query(oss.str().c_str());
      //      //
      //      if ( !result2 ) throw -4;
      //      //
      row = result->Next();
    };
  };
  if ( IsDebug() ) printf(" Moved %u runs\n",moved);
  return(0);
};

/**
 * Check if runs are good, i.e. if the tracker calibration is correctly associated..
 */
Int_t PamelaDBOperations::ValidateRuns(){
  return(this->ValidateRuns(""));
};

/**
 * Check if runs are good, i.e. if the tracker calibration is correctly associated..
 */
Int_t PamelaDBOperations::ValidateRuns(TString valfile){
  //
  TSQLResult *result = 0;
  TSQLRow    *row    = 0;
  //
  UInt_t calibtime = 50;
  //
  stringstream oss;
  oss.str("");
  //
  // =======================================================
  // validate runs by checking missing calibrations 
  // =======================================================
  UInt_t t_stop  = 0;
  UInt_t t_start = 0;
  if ( !strcmp(valfile.Data(),"") ) {
    // --------------------------------------------------------------
    // 1) get the OBT of the last run inserted after clean-time limit
    // --------------------------------------------------------------
    oss.str("");
    oss << " SELECT * FROM GL_RUN  WHERE INSERT_TIME <= '" << clean_time->AsSQLString() 
	<< "' ORDER BY RUNHEADER_TIME DESC LIMIT 1;";
    if ( IsDebug() ) printf(" Get start validation-time: query is \n %s \n",oss.str().c_str());
    result = conn->Query(oss.str().c_str());
    if ( !result ) throw -4;
    if ( !result->GetRowCount() ) {
      printf(" No runs to validate \n");
      return(1);
    }else{
      row = result->Next();
      t_start = (UInt_t)atoll(row->GetField(4));
    };  
    // --------------------------------------------------------------
    // 2) get the OBT of the last validated run
    // --------------------------------------------------------------
    oss.str("");
    //    oss << " SELECT * FROM GL_RUN  WHERE VALIDATION=1 AND RUNHEADER_TIME<="<< t_start
    oss << " SELECT * FROM GL_RUN  WHERE VALIDATION>0 AND RUNHEADER_TIME<="<< t_start
	<<" ORDER BY RUNHEADER_TIME DESC LIMIT 1;";
    if ( IsDebug() ) printf(" Get stop validation-time: query is \n %s \n",oss.str().c_str());
    result = conn->Query(oss.str().c_str());
    if ( !result ) throw -4;
    if ( result->GetRowCount() ){
      row = result->Next();
      t_stop = (UInt_t)atoll(row->GetField(4));
    };
    if ( IsDebug() ) printf("Validation interval: from time %u - to time %u \n\n",t_stop,t_start);
    // --------------------------------------------------------------
    // now retrieves runs to be validated 
    // --------------------------------------------------------------
    oss.str("");
    oss << " SELECT * FROM GL_RUN  WHERE  RUNHEADER_TIME <=" << t_start;
    oss << " AND RUNHEADER_TIME >="<< t_stop; 
    oss << " ORDER BY RUNHEADER_TIME DESC;";
    if ( IsDebug() )printf(" Check runs for validation: query is \n %s \n",oss.str().c_str());
    result = conn->Query(oss.str().c_str());
  } else {
    //
    stringstream myquery;
    UInt_t myid = 0;
    myquery.str("");
    myquery << " SELECT ID FROM GL_ROOT where NAME='"<<valfile.Data() <<"';";
    //
    result = conn->Query(myquery.str().c_str());
    //
    row = result->Next();      
    if( !row ){
      if ( strcmp(valfile.Data(),GetRootName().Data()) ){
	if ( IsDebug() ) printf(" No file to be validated even if option \"-validate file\" was used!!\n");
	return(2);
      };
      if ( IsDebug() ) printf(" No file to be validated (force mode)! \n");
      return(0);
    };
    myid=(UInt_t)atoll(row->GetField(0));
    //
    myquery.str("");
    myquery << " SELECT MAX(RUNTRAILER_TIME),MIN(RUNHEADER_TIME) FROM GL_RUN WHERE ID_ROOT_L0="<< myid <<";";
    //
    result = conn->Query(myquery.str().c_str());
    //
    row = result->Next();      
    if( !row->GetField(0) || !row->GetField(1)){ 
      //
      if ( IsDebug() ) printf(" NO RUN ASSOCIATED TO THIS FILE! \n");
      //
      return(0);
      //
    } else {  
      //
      UInt_t runhtime = (UInt_t)atoll(row->GetField(0));
      UInt_t runttime = (UInt_t)atoll(row->GetField(1));
      UInt_t caltime = 0;
      //
      myquery.str("");
      myquery << " SELECT FROM_TIME FROM GL_TRK_CALIB where FROM_TIME>" <<runhtime;
      myquery << " order by FROM_TIME asc limit 1;";
      //
      if ( IsDebug() ) printf("  query is \n %s \n",myquery.str().c_str());
      //
      //
      result = conn->Query(myquery.str().c_str());
      //
      row = result->Next();      
      if( !row ){
	caltime = runhtime;
      } else {
	caltime = (UInt_t)atoll(row->GetField(0));
      };
      //
      myquery.str("");
      myquery << " SELECT * from GL_RUN where RUNHEADER_TIME>="<< runttime <<" AND RUNHEADER_TIME<=" ;
      myquery << caltime << " order by RUNHEADER_TIME DESC";
      //
      if ( IsDebug() ) printf("  query is \n %s \n",myquery.str().c_str());
      //
      result = conn->Query(myquery.str().c_str());
      //
    };
  };
  //
  if ( !result ) throw -4;
  if ( !result->GetRowCount() && IsDebug() ) printf(" No runs to validate \n");
  //
  Int_t nrow = 0;
  GL_RUN* this_run = new GL_RUN();
  GL_RUN* next_run = new GL_RUN();
  Int_t   nseq_max = 1000;
  //  UInt_t* sequence = new UInt_t[100];
  vector<UInt_t> sequence(nseq_max);
  Int_t   nseq = 0;
  Bool_t CHECK = false;
  Bool_t this_ONLINE = false;
  Bool_t next_ONLINE = false;
  UInt_t t1=0,t2=0;
  // ---------------------------------------------------------------------------------
  // - loop over runs, back in time, 
  // - select sequences of runs close in time (less than calibtime s apart), 
  //   which could be preceeded by a calibration
  // - check if there might be a missing calibration 
  // ---------------------------------------------------------------------------------
  while(1){
	  
    row = result->Next();
    if( row == NULL ) break;
	  
    //------------
    //get run info
    //------------
    this_run->Set_GL_RUN(row);
	  	  
    Bool_t this_BAD = false;
    if(this_run->GetTRK_CALIB_USED() == 1 || this_run->GetTRK_CALIB_USED() == 2) this_ONLINE = true;
    else if (this_run->GetTRK_CALIB_USED() == 104)                          this_ONLINE = false;
    else{
      //		  printf("Missing or corrupted header!! \n");
      this_ONLINE = false;
      this_BAD = true;
    };

    //-----------------------------------
    //compare with previous(next in time)
    //-----------------------------------
    CHECK = false;
    UInt_t interval=0;
	  
    if( nrow != 0){
	
		  
      t1 = this_run->GetRUNTRAILER_TIME();
      t2 = next_run->GetRUNHEADER_TIME();
      interval = (t2-t1);
		  
      if(this_ONLINE && next_ONLINE){ 				// this: ON-LINE + next: ON-LINE
			  
	if( this_run->ID == next_run->ID_RUN_FRAG ) interval = 0;	//=> run fragments
			  
	if( interval >= calibtime )CHECK = true;			//more than calibtime s => there might be a calibration
			  
	if( !CHECK && this_run->VALIDATION ){
	  //	  for (Int_t irun = 0; irun < nseq; irun++)assignVALIDATION(sequence[irun],true);
	  for (Int_t irun = 0; irun < nseq; irun++)assignVALIDATION(sequence[irun],this_run->VALIDATION);
	  nseq=0;
	}
		  
      }else if( !this_ONLINE && next_ONLINE) { 		// this: DEFAULT + next:ON-LINE
			  
	CHECK = true;

      }else if( !next_ONLINE ){						// this:ANY + next:DEFAULT 
			  
	assignVALIDATION(next_run->ID,true);
	nseq=0;
      }
    }

    //----------------------------
    //check run sequence for calib
    //----------------------------
    if( CHECK ){
      // check if calibration exists
      if ( IsDebug() )printf("DT %i ===> CHECK Missing calibration\n",interval); 
      //      Bool_t MISSING = MissingTRK_CALIB(t1,t2);
      UInt_t MISSING = MissingTRK_CALIB(t1,t2);
      UInt_t val = 0;
      if ( MISSING == 1 ) val = 0;
      if ( MISSING == 0 ) val = 1;
      if ( MISSING == 2 ) val = 2;
      for (Int_t irun = 0; irun < nseq; irun++)assignVALIDATION(sequence[irun],val);
      nseq=0;
    };
    //--------------
    //store run info
    //--------------
    *next_run   = *this_run;
    next_ONLINE = this_ONLINE;
    if( !this_BAD ){ 
      if(nseq < nseq_max){
	sequence[nseq] = this_run->ID; 
	nseq++;
      }else printf("ValidateRuns ***WARNING*** : run sequence exceed assumed size (%i) \n",nseq_max);
    };
	  
    if ( IsDebug() ) printf("%i Run %u \n",nrow,this_run->ID);
    nrow++;
	  
  };
  delete this_run;
  delete next_run;
  //
  return(0);
};
/**
 * Check if there might be a missing tracker calibration in a given time interval
 * @param t1 From absolute time
 * @param t2 To absolute time
 * @return true if there might be a missing calibration
 */
//Bool_t PamelaDBOperations::MissingTRK_CALIB(UInt_t t1,UInt_t t2){
UInt_t PamelaDBOperations::MissingTRK_CALIB(UInt_t t1,UInt_t t2){
	
  GL_TRK_CALIB* trkcalib = new GL_TRK_CALIB();
	
  // get the closest calibration before the run start (t2)
  //  if ( trkcalib->Query_GL_TRK_CALIB(t2, conn) )return(true); 	//>>> missing
  if ( trkcalib->Query_GL_TRK_CALIB(t2, conn) )return(1); 	//>>> missing
	
  //  if ( trkcalib->TO_TIME  < t2 ) return(true); 					//>>> missing
  if ( trkcalib->TO_TIME  < t2 ) return(1); 					//>>> missing
	
  //==============================================================
  // Check is done first on the basis of time between calibration,
  // which should be equal to the time between ascending-nodes.
  //==============================================================
  if ( t2 - trkcalib->FROM_TIME > 5700) {
    if ( IsDebug() )printf("Long time between calib and run start %u :-( ==> there might be a missing calib \n",t2 - trkcalib->FROM_TIME);
    //==============================================================
    // there might be a missing calibration, due to:
    // - MM full
    // - corrupted packets
    // - loss of data
    // There is an exception in case a download was done during ascending node
    //==============================================================
    Bool_t DOWNLOAD = false;
    // check if the calib was skipped becouse of download .... DA FARE!! 
    //    if(DOWNLOAD)return(false);
    if(DOWNLOAD)return(0);
		
    //    return(true); 					//>>> missing
    return(1); 					//>>> missing
		
  };
	
  //==============================================================
  // If the last calibration is close to the run less than this time, 
  // it is enough to say that there are no missing calibrations
  //==============================================================
  // the long time interval bewteen runs might be due to download
  if ( IsDebug() )printf("Short time between calib and run start %u :-) ==> OK! \n",t2 - trkcalib->FROM_TIME);
  if ( trkcalib->VALIDATION ) return(0);
  if ( IsDebug() )printf("Calibration is not validated... :-/ ==> OK but with VALIDATION=2! \n");
  return(2);
	
};
/**
 * Assign VALIDATION value to a GL_RUN entry
 * @param idrun Run ID
 * @param validation true/false
 */
Int_t PamelaDBOperations::assignVALIDATION(UInt_t idrun, Bool_t validation){
  return(this->assignVALIDATION(idrun,(UInt_t)validation));
}

Int_t PamelaDBOperations::assignVALIDATION(UInt_t idrun, UInt_t validation){
  TSQLResult *result = 0;
  stringstream oss;
  oss.str("");
  oss << " UPDATE GL_RUN SET VALIDATION="<< (UInt_t)validation <<" WHERE ID= " << idrun << ";";
  //
  //	if ( IsDebug() ) 
  //	printf(" Set VALIDATION = %i for run %i \n",validation,idrun);
  if ( IsDebug() )printf(" Query: %s \n",oss.str().c_str());
  result = conn->Query(oss.str().c_str());
  if ( !result ) throw -4;
  return(0);
}



// Insert TLEs from file tlefilename in the table GL_TLE in the db
// opened by conn, sorting them by date from older to newer, if each
// TLE has not been alread inserted.
Int_t PamelaDBOperations::populateTLE()//(TSQLServer *conn, char *tleFile)
{
  fstream tlefile(tlefilename, ios::in);

  if ( !tlefile ) throw -7;

  vector<cTle*> ctles;
  vector<cTle*>::iterator iter;
  int present = 0;

  // Get three lines from tlefile, create a cTle object and put it
  // into ctles
  while(1) {
    cTle *tlef;
    string str1, str2, str3;

    getline(tlefile, str1);
    if(tlefile.eof()) break; 

    getline(tlefile, str2);
    if(tlefile.eof()) break;

    getline(tlefile, str3);
    if(tlefile.eof()) break;

    // We now have three good lines for a cTle.
    tlef = new cTle(str1, str2, str3);
    ctles.push_back(tlef);
  }

  tlefile.close();

  // Sort by date
  sort(ctles.begin(), ctles.end(), compTLE);

  // Now we insert each TLE into the db
  for(iter = ctles.begin(); iter != ctles.end(); iter++) {
    cTle *tle = *iter;

    // Do nothing if it's already present in the db.  Just increase
    // the counter present.
    if (! isTlePresent(tle))
      {
	int status = insertTle(tle);

	// Insert query failed.  Return 1.
	if(status == EXIT_FAILURE) {
	  
	  if( IsDebug() ) {
	    cerr << "Error: inserting TLE:" << endl
		 << tle->getName() << endl
		 << tle->getLine1() << endl
		 << tle->getLine2() << endl;
	  }

	  throw -4;
	  return 1;
	}

      }
    else
      present++;

  }

  int inserted = ctles.size() - present;  // Number of inserted TLE.
  if ( IsDebug() )
    cout << "\nProcessed TLEs ranging from " << getTleDatetime(ctles[0]) << " to " << getTleDatetime(ctles[ctles.size()-1]) << "." << endl
	 << inserted << " newly inserted TLEs out of " << ctles.size() << " processed." << endl;

  ctles.clear();


  // Return 2 if no new TLE has been inserted.  0 otherwise.
  if(! inserted ) return 2;
  return 0;
}


// Insert tle in the table GL_TLE using the connection conn.
Int_t PamelaDBOperations::insertTle(cTle *tle)
{
  stringstream oss;
  TSQLResult *result = 0;

  oss.str("");
  oss << " INSERT INTO GL_TLE (TLE1, TLE2, TLE3, FROM_TIME)"
      << " VALUES ( '" 
      << tle->getName() << "', '" 
      << tle->getLine1() << "', '"
      << tle->getLine2() << "', '"
      << getTleDatetime(tle) << "')";

  //  cout << oss.str().c_str() << endl;
  result = conn->Query(oss.str().c_str());
  if (result == NULL)
    return EXIT_FAILURE;

  return EXIT_SUCCESS;
}


// Return whether tle is already in the db connected by conn.
bool PamelaDBOperations::isTlePresent(cTle *tle)
{
  stringstream oss;
  TSQLResult *result = 0;

  oss.str("");
  oss << "SELECT * FROM GL_TLE WHERE FROM_TIME = '"
      << getTleDatetime(tle) << "'";

  result = conn->Query(oss.str().c_str());
  if (result == NULL) throw -4;

  if (result->GetRowCount())
    return true;
  else 
    return false;
}


// Return whether the first TLE is dated early than the second
bool compTLE (cTle *tle1, cTle *tle2)
{
  return getTleJulian(tle1) < getTleJulian(tle2);
}


// Return the date of the tle using the format (year-2000)*1e3 +
// julian day.  e.g. 6365 is the 31th Dec 2006.
// It does *not* return a cJulian date.
float getTleJulian(cTle *tle) {
  return tle->getField(cTle::FLD_EPOCHYEAR)*1e3 + tle->getField(cTle::FLD_EPOCHDAY);
}


// Return a string like YYYY-MM-DD hh:mm:ss, usable for mysql datetime
// format.
string getTleDatetime(cTle *tle)
{
  int year, mon, day, hh, mm, ss;
  double dom; // day of month (is double!)
  stringstream date; // date in datetime format

  // create a cJulian from the date in tle
  cJulian jdate = cJulian( 2000 + (int) tle->getField(cTle::FLD_EPOCHYEAR), tle->getField(cTle::FLD_EPOCHDAY)); 

  // get year, month, day of month
  jdate.getComponent(&year, &mon, &dom);

  // build a datetime YYYY-MM-DD hh:mm:ss
  date.str("");
  day = (int) floor(dom);
  hh = (int) floor( (dom - day) * 24);
  mm = (int) floor( ((dom - day) * 24 - hh) * 60);
  ss = (int) floor( ((((dom - day) * 24 - hh) * 60 - mm) * 60));
  //  ms = (int) floor( (((((dom - day) * 24 - hh) * 60 - mm) * 60) - ss) * 1000);

  date << year << "-" << mon << "-" << day << " " << hh << ":" << mm << ":" << ss;

  return date.str();
}

/**
 * Remove a file from the DB, delete on cascade all entries related to that file
 * rearrange GL_RUN and GL_XXX_CALIB tables, turn off validation till the following 
 * calibration
 **/
Int_t PamelaDBOperations::removeFile(TString remfile){
  //
  // Determine ID_ROOT_L0 and ID_RAW
  //
  TSQLResult *pResult;
  TSQLRow *Row;
  stringstream myquery;
  //  
  myquery.str("");
  myquery << " SELECT ID,ID_RAW,ID_TIMESYNC FROM GL_ROOT where NAME='"<<remfile.Data() <<"';";
  //
  pResult = conn->Query(myquery.str().c_str());
  //
  Row = pResult->Next();      
  if( !Row ){
    if ( strcmp(remfile.Data(),GetRootName().Data()) ){
      if ( IsDebug() ) printf(" No file to be removed even if option \"-remove file\" was used!!\n");
      return(1);
    };
    if ( IsDebug() ) printf(" No file to be removed (force mode)! \n");
    return(0);
  };
  //
  this->SetID_ROOT((UInt_t)atoll(Row->GetField(0)));
  this->SetID_RAW((UInt_t)atoll(Row->GetField(1)));
  UInt_t idtsy=(UInt_t)atoll(Row->GetField(2));
  //
  this->ValidationOFF();
  //
  this->RemoveCALIBS();
  //
  this->RemoveRUNS();
  //
  this->RemoveFILES(idtsy);
  //
  this->SetID_ROOT(0);
  this->SetID_RAW(0);
  //
  return(0);
};

/**
 * 
 * Set validation bit to zero for runs following the removing file till
 * 1) a run with TRK_CALIB_USED=140
 * 2) a run with VALIDATION = 0
 * 3) the next calibration
 *
 **/
void PamelaDBOperations::ValidationOFF(){
  TSQLResult *pResult;
  TSQLRow *Row;
  stringstream myquery;
  Int_t unv = 0;
  //select ID from GL_RUN where RUNHEADER_TIME>=1152671382 AND (VALIDATION=0 OR TRK_CALIB_USED=104) order by RUNHEADER_TIME asc limit 1;
  myquery.str("");
  myquery << " SELECT MAX(RUNTRAILER_TIME) FROM GL_RUN WHERE ID_ROOT_L0="<< this->GetID_ROOT() <<";";
  //
  pResult = conn->Query(myquery.str().c_str());
  //
  Row = pResult->Next();      
  if( !Row->GetField(0) ){ 
    //
    if ( IsDebug() ) printf(" NO RUN ASSOCIATED TO THIS FILE! \n");
    //
  } else {  
    //
    UInt_t runhtime = (UInt_t)atoll(Row->GetField(0));
    UInt_t caltime = 0;
    //
    myquery.str("");
    myquery << " SELECT FROM_TIME FROM GL_TRK_CALIB where FROM_TIME>" <<runhtime;
    myquery << " order by FROM_TIME asc limit 1;";
    //
    if ( IsDebug() ) printf("  query is \n %s \n",myquery.str().c_str());
    //
    //
    delete pResult;
    pResult = conn->Query(myquery.str().c_str());
    //
    Row = pResult->Next();      
    if( !Row ){
      caltime = runhtime;
    } else {
      caltime = (UInt_t)atoll(Row->GetField(0));
    };
    //
    myquery.str("");
    myquery << " SELECT ID,RUNHEADER_TIME from GL_RUN where RUNHEADER_TIME>="<< runhtime <<" AND (VALIDATION=0 OR TRK_CALIB_USED=104 OR RUNHEADER_TIME>" ;
    myquery << caltime << ") order by RUNHEADER_TIME asc LIMIT 1";
    //
    if ( IsDebug() ) printf("  query is \n %s \n",myquery.str().c_str());
    //
    pResult = conn->Query(myquery.str().c_str());
    //
    Row = pResult->Next();      
    if( !Row ){ 
      //
      if ( IsDebug() ) printf(" NO RUN NEED TO BE UNVALIDATED \n");
      //
    } else {
      myquery.str("");
      myquery << " SELECT ID from GL_RUN where RUNHEADER_TIME<"<< Row->GetField(1) <<" AND ";
      myquery << " RUNHEADER_TIME>=" <<runhtime;
      myquery << " order by RUNHEADER_TIME asc;";
      //
      if ( IsDebug() ) printf("  query is \n %s \n",myquery.str().c_str());
      //
      pResult = conn->Query(myquery.str().c_str());
      //
      Row = pResult->Next();  
      while ( Row ){
	//	
	unv++;
	this->assignVALIDATION((UInt_t)atoll(Row->GetField(0)), false);
	Row = pResult->Next();  
	//
      };
    };
  };
  if ( IsDebug() ) printf(" %u runs have been unvalidated \n",unv);
};

/**
 * 
 * Rearrange GL_RUN table and remove runs
 *
 **/
void PamelaDBOperations::RemoveRUNS(){
  TSQLResult *pResult;
  TSQLRow *Row;
  stringstream myquery;
  UInt_t drun = 0;
  GL_RUN *delrun = new GL_RUN();
  //
  myquery.str("");
  myquery << " SELECT ID FROM GL_RUN where ID_RUN_FRAG=0 and ID_ROOT_L0=" <<this->GetID_ROOT() <<";";
  //
  if ( IsDebug() ) printf("  query is \n %s \n",myquery.str().c_str());
  //
  pResult = conn->Query(myquery.str().c_str());
  //
  Row = pResult->Next();     
  //
  //
  if ( !Row ){
    if ( IsDebug() ) printf(" No run with ID_RUN_FRAG=0 belonged to this file \n");
  } else {
    if ( IsDebug() ) printf(" Deleting run from GL_RUN table \n");    
    while ( Row ){
      delrun->DeleteRun(conn,(UInt_t)atoll(Row->GetField(0)),"GL_RUN");
      if ( IsDebug() ) printf(" del run %u \n",(UInt_t)atoll(Row->GetField(0)));
      drun++;
      Row = pResult->Next();     
    };
  };
  //
  //
  myquery.str("");
  myquery << " SELECT ID,ID_RUN_FRAG FROM GL_RUN where ID_RUN_FRAG!=0 and ID_ROOT_L0=" <<this->GetID_ROOT() <<";";
  //
  if ( IsDebug() ) printf("  query is \n %s \n",myquery.str().c_str());
  //
  pResult = conn->Query(myquery.str().c_str());
  //
  Row = pResult->Next();     
  // 
  if ( !Row ){
    if ( IsDebug() ) printf(" No run with ID_RUN_FRAG!=0 belonged to this file \n");
  } else {
    if ( IsDebug() ) printf(" Deleting run fragments from GL_RUN table \n");    
    while ( Row ){
      if ( IsDebug() ) printf(" restore run %u \n",(UInt_t)atoll(Row->GetField(1)));
      delrun->RestoreRun(conn,(UInt_t)atoll(Row->GetField(1)),"GL_RUN_FRAGMENTS");
      if ( IsDebug() ) printf(" del run %u \n",(UInt_t)atoll(Row->GetField(1)));
      delrun->DeleteRun(conn,(UInt_t)atoll(Row->GetField(1)),"GL_RUN");
      if ( (UInt_t)atoll(Row->GetField(1)) != (UInt_t)atoll(Row->GetField(0)) ){
	if ( IsDebug() ) printf(" del run %u \n",(UInt_t)atoll(Row->GetField(0)));
	delrun->DeleteRun(conn,(UInt_t)atoll(Row->GetField(0)),"GL_RUN");
      };
      drun++;
      Row = pResult->Next();     
    };
  };
  //
  if ( IsDebug() ) printf(" Deleted %i run(s) from GL_RUN table \n",drun);    
  //
  //
  //
  drun = 0;
  //
  myquery.str("");
  myquery << " SELECT ID_TRASH FROM GL_RUN_TRASH where BELONGED_TO='GL_RUN_FRAGMENTS' AND ID_ROOT_L0=" <<this->GetID_ROOT() <<";";
  //
  pResult = conn->Query(myquery.str().c_str());
  //
  Row = pResult->Next();     
  // 
  if ( !Row ){
    if ( IsDebug() ) printf(" No run from GL_RUN_FRAGMENTS table in the trash table for this file \n");
  } else {
    if ( IsDebug() ) printf(" Deleting run fragments from GL_RUN_TRASH table \n");    
    while ( Row ){
      if ( IsDebug() ) printf(" del run idtrash %u \n",(UInt_t)atoll(Row->GetField(0)));
      myquery.str("");
      myquery << " DELETE FROM GL_RUN_TRASH where ID_TRASH=" << Row->GetField(0) <<";";      
      conn->Query(myquery.str().c_str());
      drun++;
      Row = pResult->Next();     
    };
  };
  //  
  if ( IsDebug() ) printf(" Deleted %u run(s) from GL_RUN_TRASH table \n",drun);    
  //
  //
  //
  drun = 0;
  //
  myquery.str("");
  myquery << " SELECT ID FROM GL_RUN_FRAGMENTS where ID_ROOT_L0=" <<this->GetID_ROOT() <<";";
  //
  pResult = conn->Query(myquery.str().c_str());
  //
  Row = pResult->Next();     
  // 
  if ( !Row ){
    if ( IsDebug() ) printf(" No run in the GL_RUN_FRAGMENTS table for this file \n");
  } else {
    if ( IsDebug() ) printf(" Deleting run fragments from GL_RUN_FRAGMENTS table \n");    
    while ( Row ){
      if ( IsDebug() ) printf(" del run %u \n",(UInt_t)atoll(Row->GetField(0)));
      myquery.str("");
      myquery << " DELETE FROM GL_RUN_FRAGMENTS where ID=" << Row->GetField(0) <<";";
      conn->Query(myquery.str().c_str());
      drun++;
      Row = pResult->Next();     
    };
  };
  //  
  if ( IsDebug() ) printf(" Deleted %u run(s) from GL_RUN_FRAGMENTS table \n",drun);    
  //
  //
  //
  delete delrun;
  //
};


/**
 * 
 * Rearrange calibration tables
 *
 **/
void PamelaDBOperations::RemoveFILES(UInt_t idtsy){
  stringstream myquery;
  //
  myquery.str("");
  myquery << " DELETE FROM GL_RAW WHERE ID=" <<this->GetID_RAW() <<";";
  //
  if ( IsDebug() ) printf("  query is \n %s \n",myquery.str().c_str());
  //
  conn->Query(myquery.str().c_str());
  //
  myquery.str("");
  myquery << " DELETE FROM GL_ROOT WHERE ID=" <<this->GetID_ROOT() <<";";
  //
  if ( IsDebug() ) printf("  query is \n %s \n",myquery.str().c_str());
  //
  conn->Query(myquery.str().c_str());  //
  //
  if ( !chewbacca ){
    myquery.str("");
    myquery << " DELETE FROM GL_TIMESYNC WHERE ID=" << idtsy <<";";
    //
    if ( IsDebug() ) printf("  query is \n %s \n",myquery.str().c_str());
    //
    conn->Query(myquery.str().c_str());
  };
  //
};

/**
 * 
 * Rearrange calibration tables
 *
 **/
void PamelaDBOperations::RemoveCALIBS(){
  TSQLResult *pResult;
  TSQLRow *Row;
  stringstream myquery;
  //  
  //
  // Calorimeter
  //
  for (Int_t section = 0; section < 4; section++){
    myquery.str("");
    myquery << " SELECT MIN(FROM_TIME),MAX(TO_TIME) FROM GL_CALO_CALIB WHERE ID_ROOT_L0="<< this->GetID_ROOT() <<" AND ";
    myquery << " SECTION=" << section << ";";
    //
    pResult = conn->Query(myquery.str().c_str());
    //
    Row = pResult->Next();      
    if( !Row->GetField(0) || !Row->GetField(1) ){ 
      //
      if ( IsDebug() ) printf(" NO CALO CALIBRATION SECTION %i ASSOCIATED TO THIS FILE! \n",section);
      //
    } else {
      //
      myquery.str("");
      myquery << " UPDATE GL_CALO_CALIB SET TO_TIME=" << Row->GetField(1);
      myquery << " WHERE TO_TIME="<< Row->GetField(0) << " AND ";
      myquery << " SECTION=" << section << ";";
      //
      pResult = conn->Query(myquery.str().c_str());
      //
      if( !pResult ){
	//
	if ( IsDebug() ) printf(" ERROR DELETING CALO CALIBRATIONS \n");
	//
	throw -4;
	//
      };
      //
    };
  };
  Bool_t OLDDB = false;
  for (Int_t section = 0; section < 4; section++){
    myquery.str("");
    myquery << " SELECT MIN(FROM_TIME),MAX(TO_TIME) FROM GL_CALOPULSE_CALIB WHERE ID_ROOT_L0="<< this->GetID_ROOT() <<" AND ";
    myquery << " SECTION=" << section << ";";
    //
    pResult = conn->Query(myquery.str().c_str());
    //
    if ( conn->GetErrorCode() ){
      printf(" Section %i : warning, old databse structure no GL_CALOPULSE_CALIB table!\n",section);
      OLDDB=true;
    } else {
      Row = pResult->Next();      
      if( !Row->GetField(0) || !Row->GetField(1) ){ 
	//
	if ( IsDebug() ) printf(" NO PULSE CALO CALIBRATION SECTION %i ASSOCIATED TO THIS FILE! \n",section);
	//
      } else {
	//
	myquery.str("");
	myquery << " UPDATE GL_CALOPULSE_CALIB SET TO_TIME=" << Row->GetField(1);
	myquery << " WHERE TO_TIME="<< Row->GetField(0) << " AND ";
	myquery << " SECTION=" << section << ";";
	//
	pResult = conn->Query(myquery.str().c_str());
	//
	if( !pResult ){
	  //
	  if ( IsDebug() ) printf(" ERROR DELETING CALO PULSE CALIBRATIONS \n");
	  //
	  throw -4;
	  //
	};
	//
      };
    };
  };
  myquery.str("");
  myquery << " DELETE FROM GL_CALO_CALIB WHERE ID_ROOT_L0=" << this->GetID_ROOT() << ";";
  //
  pResult = conn->Query(myquery.str().c_str());
  //
  if( !pResult ){
    //
    if ( IsDebug() ) printf(" ERROR DELETING CALO CALIBRATIONS \n");
    //
    throw -4;
    //
  };
  //
  myquery.str("");
  myquery << " DELETE FROM GL_CALOPULSE_CALIB WHERE ID_ROOT_L0=" << this->GetID_ROOT() << ";";
  //
  pResult = conn->Query(myquery.str().c_str());
  if ( IsDebug() ) printf(" Delete from GL_CALOPULSE_CALIB query is %s \n",myquery.str().c_str());
  if ( !OLDDB ){
    //
    if( !pResult ){
      //
      if ( IsDebug() ) printf(" ERROR DELETING PULSE CALO CALIBRATIONS \n");
      //
      throw -4;
      //
    };
  };
  //
  // Tracker
  //
  myquery.str("");
  myquery << " SELECT MIN(FROM_TIME),MAX(TO_TIME) FROM GL_TRK_CALIB WHERE ID_ROOT_L0="<< this->GetID_ROOT() <<";";
  //
  pResult = conn->Query(myquery.str().c_str());
  //
  Row = pResult->Next();      
  if( !Row->GetField(0) || !Row->GetField(1) ){ 
    //
    if ( IsDebug() ) printf(" NO TRK CALIBRATION ASSOCIATED TO THIS FILE! \n");
    //
  } else {
    //
    myquery.str("");
    myquery << " UPDATE GL_TRK_CALIB SET TO_TIME=" << Row->GetField(1);
    myquery << " WHERE TO_TIME="<< Row->GetField(0) << ";";
    //
    pResult = conn->Query(myquery.str().c_str());
    //
    if( !pResult ){
      //
      if ( IsDebug() ) printf(" ERROR DELETING TRK CALIBRATIONS \n");
      //
      throw -4;
      //
    };
    //
    myquery.str("");
    myquery << " DELETE FROM GL_TRK_CALIB WHERE ID_ROOT_L0=" << this->GetID_ROOT() << ";";
    //
    pResult = conn->Query(myquery.str().c_str());
    //
    if( !pResult ){
      //
      if ( IsDebug() ) printf(" ERROR DELETING TRK CALIBRATIONS \n");
      //
      throw -4;
      //
    };
  };
  //
  //
  // S4
  //
  myquery.str("");
  myquery << " SELECT MIN(FROM_TIME),MAX(TO_TIME) FROM GL_S4_CALIB WHERE ID_ROOT_L0="<< this->GetID_ROOT() <<";";
  //
  pResult = conn->Query(myquery.str().c_str());
  //
  Row = pResult->Next();      
  if( !Row->GetField(0) || !Row->GetField(1) ){ 
    //
    if ( IsDebug() ) printf(" NO S4 CALIBRATION ASSOCIATED TO THIS FILE! \n");
    //
  } else {
    //
    myquery.str("");
    myquery << " UPDATE GL_S4_CALIB SET TO_TIME=" << Row->GetField(1);
    myquery << " WHERE TO_TIME="<< Row->GetField(0) << ";";
    //
    pResult = conn->Query(myquery.str().c_str());
    //
    if( !pResult ){
      //
      if ( IsDebug() ) printf(" ERROR DELETING S4 CALIBRATIONS \n");
      //
      throw -4;
      //
    };
    //
    myquery.str("");
    myquery << " DELETE FROM GL_S4_CALIB WHERE ID_ROOT_L0=" << this->GetID_ROOT() << ";";
    //
    pResult = conn->Query(myquery.str().c_str());
    //
    if( !pResult ){
      //
      if ( IsDebug() ) printf(" ERROR DELETING S4 CALIBRATIONS \n");
      //
      throw -4;
      //
    };
    //
  };
};

/**
 * 
 * Rearrange calibration tables
 *
 **/
UInt_t PamelaDBOperations::ValidateTrkCalib( CalibTrk1Event* caltrk, EventHeader *eh , TFile *file){

    if(!caltrk) return 0;

    if ( IsDebug() ) cout << "ValidateTrkCalib:"<<endl;

    UInt_t validate = 1;
    Int_t vorder[]={5,5,3,3,4,4,2,2,1,1,0,0};
    UInt_t timeaftercalib=120000; //2000;
    TString classname = caltrk->GetName();

//  ----------------------------------
//  Check CRCs and failed calibrations
//  ----------------------------------
    for(Int_t ipkt=0; ipkt<6; ipkt++){
	if(caltrk->DSPnumber[ipkt]>0 && caltrk->DSPnumber[ipkt]<=12){
	    if( caltrk->crc_hcal[ipkt] ){
//		if(IsDebug())cout<<"(CRC Header)";
		validate = 0;
		if(IsDebug())cout <<endl<<" *** CRC *** (header DSPn "<<caltrk->DSPnumber[ipkt]<<")";
	
	    }
	    for(Int_t ilad=0; ilad<3; ilad++)if( caltrk->crc_cal[ipkt][ilad] ){
//		if(IsDebug())cout<<"(CRC Pkt-"<<ilad<<")";
		if(IsDebug())cout <<endl<<" *** CRC *** (data DSPn "<<caltrk->DSPnumber[ipkt]<<" ladder "<<ilad<<")";
		validate = 0;
	    }
	    if( !(caltrk->ncalib_event[ipkt]==0 && caltrk->cal_flag[ipkt]==0) ){
		if(IsDebug())cout <<endl<<" *** FAILURE *** 	(data DSPn "<<caltrk->DSPnumber[ipkt]<<")";
		validate = 0;
	    }
	}else{
// 	    validate=0;
 	    if(IsDebug())cout <<endl<<" *** DSPn *** ("<< caltrk->DSPnumber[ipkt] <<" @pkt "<<ipkt<<")";
	}
    }

//  -----------------------
//  Check missing packets:
//  -----------------------
//    Readout order:
//    ------------------
//    DSP   packet board
//    ------------------
//    12    0      1
//    10    1      1
//     8    2      1
//     4    3      1
//     6    4      1
//     2    5      1
//    ------------------
//    11    0      2
//     9    1      2
//     7    2      2
//     3    3      2
//     5    4      2
//     1    5      2
//    ------------------
//  -------------------------------------------------
//  Check if it is first or second calibration packet
//  -------------------------------------------------
    UInt_t build=0;
    UInt_t base=0;
    UInt_t mask=0;
    if(classname.Contains("CalibTrk1Event")){
	base=12;
	mask=0x03F000; 
    }
    if(classname.Contains("CalibTrk2Event")){
	base=18;
	mask=0xFC0000; 
    }
//  ----------------------------------------------------
//  Count number of valid packets and set build variable
//  ----------------------------------------------------
    if(IsDebug())cout <<endl<< " DSP: ";
    Int_t  npkts=0;
    for(Int_t ipkt=0; ipkt<6; ipkt++){
	if(caltrk->DSPnumber[ipkt]>0 && caltrk->DSPnumber[ipkt]<=12){
	    if(IsDebug())cout <<" "<<caltrk->DSPnumber[ipkt];
	    npkts++;
	    build = build | ( 1<<(base+vorder[caltrk->DSPnumber[ipkt]-1]) );
// 	    cout << caltrk->DSPnumber[ipkt]
	};
    }
    if(IsDebug())cout << " ==> "<< hex << build << dec;
//  ----------------------------------------------------
//  If the number of valid packets is 6, ok exit...
//  ----------------------------------------------------
    if( npkts==6 ){
	return validate; // exit
    }
////////////////////////////////////////////////////////
//  ...otherwise there might be some missing packets
//
//  In this case check the acq configuration
//  (some DSPs might be excluded from acquisition)
////////////////////////////////////////////////////////

    if(!eh || !file || (file&&file->IsZombie()) ){
	if ( IsDebug() )cout << " *** MISSING VIEW *** eh="<<eh<<" file="<<file<<" cannot validate"<<endl;
	return (0);
    }
    
//  -----------------------------------------------
//  retrieve the first run header after calib
//  -----------------------------------------------
    
    PacketType *pctp;
    EventCounter *cod;
    cod = eh->GetCounter();
    Int_t irun = cod->Get(pctp->RunHeader);
    TTree *rh=(TTree*)file->Get("RunHeader");
    if ( !rh || rh->IsZombie() ) throw -17;
    if( rh->GetEntries() <= irun ){ 
	if ( IsDebug() ) cout << " *** MISSING-PKT *** no runs after calib (1) -- cannot validate :-( "<<endl;
	return 0; // :-(
    }
    RunHeaderEvent *run  = 0;
    EventHeader    *hrun = 0;
    rh->SetBranchAddress("RunHeader", &run);
    rh->SetBranchAddress("Header", &hrun);
    rh->GetEntry(irun);    
    if( OBT(hrun->GetPscuHeader()->GetOrbitalTime()) < OBT(eh->GetPscuHeader()->GetOrbitalTime())){
	if ( IsDebug() ) cout << " *** MISSING-PKT *** no runs after calib (2) -- cannot validate :-( "<<endl;
	return 0; // :-(
    }

    UInt_t dtime = OBT(hrun->GetPscuHeader()->GetOrbitalTime()) - OBT(eh->GetPscuHeader()->GetOrbitalTime());
    if( dtime > timeaftercalib ){
	if ( IsDebug() ) cout << " *** MISSING-PKT *** run after calib too far ( "<<dtime<<"ms ) -- cannot validate :-( "<<endl;
	return 0; // :-(
    }

    if ( IsDebug() ) cout <<endl<< " ACQ_BUILD_INFO ==> "<<hex<<(run->ACQ_BUILD_INFO & mask)<<dec;

    if( (run->ACQ_BUILD_INFO & mask) != build ){
	validate=0; // :-(
	cout <<endl<< " *** MISSING-PKT *** packet mismatch: ACQ_BUILD_INFO="<<hex<<(run->ACQ_BUILD_INFO&mask)<<" != "<<build<<dec;
    };

    return validate;


}

/**
 * 
 * Check the DB (only for overlapping runs at the moment)
 *
 **/
UInt_t PamelaDBOperations::Check(){
  return(this->Check(0,0));
}

UInt_t PamelaDBOperations::Check(UInt_t from, UInt_t to){
  //
  if ( IsDebug() ) printf(" from %u to %u \n",from,to);
  //
  UInt_t test = 0;
  //
  UInt_t thisrht = 0;
  UInt_t thisrtt = 0;
  UInt_t thisid = 0;
  UInt_t prevrht = 0;
  UInt_t prevrtt = 0;
  UInt_t previd = 0;
  //
  UInt_t prevl0id = 0;
  UInt_t thisl0id = 0;
  //
  stringstream oss;
  TSQLResult *result = 0;
  TSQLRow    *row    = 0;
  TSQLResult *result2 = 0;
  TSQLRow    *row2    = 0;
  TSQLResult *result3 = 0;
  TSQLRow    *row3    = 0;
  oss.str("");
  oss << "SELECT ID,ID_ROOT_L0,RUNHEADER_TIME,RUNTRAILER_TIME,NEVENTS FROM GL_RUN order by RUNHEADER_TIME asc;";
  //  oss << "SELECT ID,RUNHEADER_TIME,RUNTRAILER_TIME FROM GL_RUN where ID>10170 and ID<10190 order by RUNHEADER_TIME asc;";
  result = conn->Query(oss.str().c_str());
  //
  if ( !result ) throw -4;;
  //
  row = result->Next();
  UInt_t nid = 0;
  //
  while ( row ){
    nid++;
    if ( !(nid%1000) && nid ) printf(" %iK run scanned \n",nid/1000);
    thisid = (UInt_t)atoll(row->GetField(0));
    thisl0id = (UInt_t)atoll(row->GetField(1));
    thisrht = (UInt_t)atoll(row->GetField(2));
    thisrtt = (UInt_t)atoll(row->GetField(3));
    //
    if ( from > 0 && nid <= from ) goto ss;
    if ( to > 0 && nid >= to ) goto ss;
    //
    if ( (UInt_t)atoll(row->GetField(4)) > 1 ){
      //
      //
      //
      oss.str("");
      oss << "SELECT ID,ID_ROOT_L0,RUNHEADER_TIME,RUNTRAILER_TIME FROM GL_RUN WHERE ID!="
	  << thisid << " AND ( RUNHEADER_TIME="
	  << thisrht << " OR RUNTRAILER_TIME=" 
	  << thisrtt << " ) AND NEVENTS!=0 AND NEVENTS!=1 order by RUNHEADER_TIME asc;";
      result3 = conn->Query(oss.str().c_str());
      if ( IsDebug() ) printf(" query is %s \n",oss.str().c_str());
      if ( result3 ){
	//
	oss.str("");
	oss << "SELECT ID,ID_ROOT_L0,RUNHEADER_TIME,RUNTRAILER_TIME FROM GL_RUN WHERE ID!="
	    << thisid << " AND RUNHEADER_TIME="
	    << thisrht << " AND RUNTRAILER_TIME!=" 
	    << thisrtt << " AND NEVENTS!=0 AND NEVENTS!=1 order by RUNHEADER_TIME asc;";
	result3 = conn->Query(oss.str().c_str());
	if ( IsDebug() ) printf(" query is %s \n",oss.str().c_str());
	if ( result3 ){
	  row3 = result3->Next();
	  //
	  while ( row3 ){
	    //
	    // 2 runs with same runheader
	    //
	    printf(" CHECK n.4 RUNs %u and %u HAVE SAME RUNHEADER \n",thisid,(UInt_t)atoll(row3->GetField(0)));	  
	    row3 = result3->Next();
	  };
	  //	delete result3;

	};
	//
	oss.str("");
	oss << "SELECT ID,ID_ROOT_L0,RUNHEADER_TIME,RUNTRAILER_TIME FROM GL_RUN WHERE ID!="
	    << thisid << " AND RUNHEADER_TIME!="
	    << thisrht << " AND RUNTRAILER_TIME=" 
	    << thisrtt << " AND NEVENTS!=0 AND NEVENTS!=1 order by RUNHEADER_TIME asc;";
	result3 = conn->Query(oss.str().c_str());
	if ( IsDebug() ) printf(" query is %s \n",oss.str().c_str());
	if ( result3 ){
	  row3 = result3->Next();
	  //
	  while ( row3 ){
	    //
	    // 2 runs with same runtrailer
	    //
	    printf(" CHECK n.5 RUNs %u and %u HAVE SAME RUNTRAILER \n",thisid,(UInt_t)atoll(row3->GetField(0)));
	    row3 = result3->Next();
	  };
	  //	delete result3;
	};
	//
	oss.str("");
	oss << "SELECT ID,ID_ROOT_L0,RUNHEADER_TIME,RUNTRAILER_TIME FROM GL_RUN WHERE ID!="
	    << thisid << " AND RUNHEADER_TIME="
	    << thisrht << " AND RUNTRAILER_TIME=" 
	    << thisrtt << " AND ID_RUN_FRAG!="
	    << thisid << " order by RUNHEADER_TIME asc;";
	result3 = conn->Query(oss.str().c_str());
	if ( result3 ){
	  row3 = result3->Next();
	  //
	  while ( row3 ){
	    //
	    // duplicated run
	    //
	    printf(" CHECK n.7 RUNs %u and %u HAVE SAME RUNTRAILER AND RUNHEADER (ARE THE SAME?) \n",thisid,(UInt_t)atoll(row3->GetField(0)));
	    row3 = result3->Next();
	  };
	  //	delete result3;

	};
      };
      //
      oss.str("");
      oss << "SELECT ID,ID_ROOT_L0,RUNHEADER_TIME,RUNTRAILER_TIME FROM GL_RUN WHERE ID!="
	  << thisid << " AND RUNHEADER_TIME>"
	  << thisrht << " AND RUNTRAILER_TIME<" 
	  << thisrtt << " order by RUNHEADER_TIME asc;";
      result3 = conn->Query(oss.str().c_str());
      if ( result3 ){
	row3 = result3->Next();
	//
	while ( row3 ){
	  //
	  // run contained in the checked one
	  //
	  printf(" CHECK n.6 RUN %u CONTAINS RUN %u  \n",thisid,(UInt_t)atoll(row3->GetField(0)));
	  row3 = result3->Next();
	};
	//	delete result3;
      };
      //
    };
    //
    //    if ( thisrht < prevrtt || thisrtt < prevrht || thisrht > thisrtt && !(!prevrht && !prevrtt &&!previd) ){
    //    if ( (thisrht < prevrtt || thisrtt < prevrht || thisrht > thisrtt) && (thisrht != prevrht) ){
    if ( (thisrht < prevrtt) && (thisrht != prevrht) ){
      if ( IsDebug() ) printf(" IDprev %u ID %u    prevrht %u prevrtt %u  thisrht %u thisrtt %u \n",previd,thisid,prevrht,prevrtt,thisrht,thisrtt);
      printf(" CHECK n.1 TIME SCREW of %i s AROUND RUNs %u and %u \n",(thisrht-prevrtt),previd,thisid);
      TString prevf = "";
      TString thisf = "";
      oss.str("");
      oss << "SELECT NAME FROM GL_ROOT where ID=" << (UInt_t)prevl0id <<";";
      result2 = conn->Query(oss.str().c_str());
      if ( !result2 ) throw -4;;
      row2 = result2->Next();
      prevf = (TString)row2->GetField(0);
      oss.str("");
      oss << "SELECT NAME FROM GL_ROOT where ID=" << (UInt_t)thisl0id <<";";
      result2 = conn->Query(oss.str().c_str());
      if ( !result2 ) throw -4;;
      row2 = result2->Next();
      thisf = (TString)row2->GetField(0);
      if ( IsDebug() ) printf(" ==> files %s and %s \n",prevf.Data(),thisf.Data());
      test = 1;
      //	delete result2;
    };
    //
    if ( (thisrtt < prevrht) && (thisrht != prevrht) ){
      if ( IsDebug() ) printf(" IDprev %u ID %u    prevrht %u prevrtt %u  thisrht %u thisrtt %u \n",previd,thisid,prevrht,prevrtt,thisrht,thisrtt);
      printf(" CHECK n.2 TIME SCREW of %i s AROUND RUNs %u and %u \n",(thisrtt-prevrht),previd,thisid);
      TString prevf = "";
      TString thisf = "";
      oss.str("");
      oss << "SELECT NAME FROM GL_ROOT where ID=" << (UInt_t)prevl0id <<";";
      result2 = conn->Query(oss.str().c_str());
      if ( !result2 ) throw -4;
      row2 = result2->Next();
      prevf = (TString)row2->GetField(0);
      oss.str("");
      oss << "SELECT NAME FROM GL_ROOT where ID=" << (UInt_t)thisl0id <<";";
      result2 = conn->Query(oss.str().c_str());
      if ( !result2 ) throw -4;;
      row2 = result2->Next();
      thisf = (TString)row2->GetField(0);
      if ( IsDebug() ) printf(" ==> files %s and %s \n",prevf.Data(),thisf.Data());
      test = 1;
      //	delete result2;
    };
    //
    if ( (thisrht > thisrtt) && (thisrht != prevrht) ){
      if ( IsDebug() ) printf(" IDprev %u ID %u    prevrht %u prevrtt %u  thisrht %u thisrtt %u \n",previd,thisid,prevrht,prevrtt,thisrht,thisrtt);
      printf(" CHECK n.3 TIME SCREW of %i s AROUND RUNs %u and %u \n",(thisrht-thisrtt),previd,thisid);
      TString prevf = "";
      TString thisf = "";
      oss.str("");
      oss << "SELECT NAME FROM GL_ROOT where ID=" << (UInt_t)prevl0id <<";";
      result2 = conn->Query(oss.str().c_str());
      if ( !result2 ) throw -4;;
      row2 = result2->Next();
      prevf = (TString)row2->GetField(0);
      oss.str("");
      oss << "SELECT NAME FROM GL_ROOT where ID=" << (UInt_t)thisl0id <<";";
      result2 = conn->Query(oss.str().c_str());
      if ( !result2 ) throw -4;;
      row2 = result2->Next();
      thisf = (TString)row2->GetField(0);
      if ( IsDebug() ) printf(" ==> files %s and %s \n",prevf.Data(),thisf.Data());
      test = 1;
      //	delete result2;
    };
  ss:
    //
    prevrht = thisrht;
    prevrtt = thisrtt;
    previd = thisid;
    prevl0id = thisl0id;
    row = result->Next();
    //    if ( result2 ) delete result2;
    //    if ( result3 ) delete result3;
  };
  //
  return(test);
  //
};
