#if !defined(__CINT__) || defined(__MAKECINT__)


#include <fstream>
#include <sstream>
#include <string>
#include <math.h>
#include <iostream>
#include <TTree.h>
#include <TClassEdit.h>
#include <TObject.h>
#include <TList.h>
#include <TSystem.h>
#include <TSystemDirectory.h>
#include <TString.h>
#include <TFile.h>
#include <TClass.h>
#include <TCanvas.h>
#include <TH1.h>
#include <TH1F.h>
#include <TH2D.h>
#include <TLatex.h>
#include <TPad.h>
#include <TPaveLabel.h>
#include <TChain.h>
#include <TGraph.h>
#include <TMultiGraph.h>
#include <TLine.h>
#include <TStyle.h>
#include <TF1.h>
#include <TH1F.h>
#include <TTree.h>
#include <TCanvas.h>
#include <PamLevel2.h>
#include <iomanip>
//
#include <ToFCore.h>
//
// Declaration of the core fortran routines
//
#define tofl2com tofl2com_
extern "C" int tofl2com();
#define toftrk toftrk_
extern "C" int toftrk();
///extern "C" int toftrk(float);
#define rdtofcal rdtofcal_
//extern "C" int rdtofcal(char [], int *);
extern "C" int rdtofcal(const char *, int *);

using namespace std;

#endif

//===================================
// global variables
//===================================
TString   DIR;
TString   OUTF;
TString   LIST;
TString   OPTIONS;
TString   CALIBF;

PamLevel2 *pam_event = NULL;

//==========================================
//000000000000000000000000000000000000000000
//==========================================
Int_t Loop(TString ddir,TString list, TString options){
  //
  //
  extern struct ToFInput  tofinput_;
  extern struct ToFOutput tofoutput_;
  //  --------------------
  //  read input file/list
  //  --------------------
  pam_event = new PamLevel2(ddir,list,options);
  pam_event->SetSELLI(2);
  TTree::SetMaxTreeSize(1000*Long64_t(2000000000)); 
  //
  TString outfile_t = "";
  outfile_t = OUTF;
  outfile_t.Append(".root");
  TFile *outft = (TFile*)gROOT->FindObject(outfile_t); 
  if (outft) outft->Close();
  outft = new TFile(outfile_t,"RECREATE");
  if(outft->IsZombie()){
    cout << "Output file could not be created\n";
    return 1;
  };
  cout << "Created output file: "<<outft->GetName()<<endl;
  //
  outft->cd();
  ToFLevel2 *tof = new ToFLevel2();
  ToFdEdx *tofdedx = new ToFdEdx();
  TTree *toft = new TTree("ToF","PAMELA Level2 ToF data");
  toft->SetAutoSave(900000000000000LL);  	 
  tof->Set();//ELENA **TEMPORANEO?**
  toft->Branch("ToFLevel2","ToFLevel2",&tof);
  //
  pam_event->CreateCloneTrees(outft);
  //
  Int_t ntrkentry = 0;
  Int_t npmtentry = 0;
  Float_t xleft=0;
  Float_t xright=0;
  Float_t yleft=0;
  Float_t yright=0;
  //
  ULong64_t nevents = pam_event->GetEntries();
  printf("\n\n Running on %llu events \n\n",nevents);
  //
  TFile *tfile = TFile::Open(list.Data(),"READ");
  TTree *toftr = (TTree*)tfile->Get("ToF");
  ToFLevel2 *tofl2 = new ToFLevel2();
  toftr->SetBranchAddress("ToFLevel2", &tofl2);
  ULong64_t ntofev = toftr->GetEntries();
  printf(" ToF events are %llu \n",ntofev);
  //
  //
  GL_PARAM *glparam = new GL_PARAM();
  TrkLevel2 *trk = new TrkLevel2();
  //
  TString host;
  TString user;
  TString psw;
  const char *pamdbhost=gSystem->Getenv("PAM_DBHOST");
  const char *pamdbuser=gSystem->Getenv("PAM_DBUSER");
  const char *pamdbpsw=gSystem->Getenv("PAM_DBPSW");
  if ( !pamdbhost ) pamdbhost = "";
  if ( !pamdbuser ) pamdbuser = "";
  if ( !pamdbpsw ) pamdbpsw = "";
  if ( strcmp(pamdbhost,"") ) host = pamdbhost;
  if ( strcmp(pamdbuser,"") ) user = pamdbuser;
  if ( strcmp(pamdbpsw,"") ) psw = pamdbpsw;
  //
  //
  TSQLServer *dbc = TSQLServer::Connect(host.Data(),user.Data(),psw.Data());
  if ( !dbc->IsConnected() ) return 1;
  stringstream myquery;
  myquery.str("");
  myquery << "SET time_zone='+0:00'";
  dbc->Query(myquery.str().c_str());
  glparam->Query_GL_PARAM(1,1,dbc); // parameters stored in DB in GL_PRAM table
  trk->LoadField(glparam->PATH+glparam->NAME);
  //
  Long64_t myrun = 0;
  Long64_t mysrun = -1;
  Int_t adc[4][12];
  Int_t tdc[4][12];
  Float_t tdcc[4][12];
  //
  Bool_t defcal = true;
  for(ULong64_t iev=0; iev<nevents; iev++){      


    //==================================================================


    //  for(ULong64_t iev=0; iev<50; iev++){      
    //
    if ( !(iev%1000) ) printf(" %iK \n",(int)iev/1000);
    pam_event->Clear();
    //
    if( pam_event->GetEntry(iev) ){
      //
      pam_event->FillCloneTrees();
      toftr->GetEntry(iev);
      //
      // variable to save information about the tof calibration used
      //
      //
      myrun=pam_event->GetRunInfo()->ID;
      if ( myrun != mysrun ){
	//	printf(" rhtime %u myrun %i mysrun %i \n",pam_event->GetRunInfo()->RUNHEADER_TIME,(int)myrun,(int)mysrun);
	mysrun = myrun;
	//




	Int_t error=glparam->Query_GL_PARAM(pam_event->GetRunInfo()->RUNHEADER_TIME,204,dbc); // parameters stored in DB in GL_PRAM table
	if ( error<0 ) {
	  return(1);
	};
	//
	tofdedx->ReadParAtt((glparam->PATH+glparam->NAME).Data());
	printf(" Reading Attenuation file: %s \n",(glparam->PATH+glparam->NAME).Data());	

	//
	error=glparam->Query_GL_PARAM(pam_event->GetRunInfo()->RUNHEADER_TIME,205,dbc); // parameters stored in DB in GL_PRAM table
	if ( error<0 ) {
	  return(1);
	};
	//
	tofdedx->ReadParPos((glparam->PATH+glparam->NAME).Data());
	printf(" Reading desaturation1 file: %s \n",(glparam->PATH+glparam->NAME).Data());

	//
	error=glparam->Query_GL_PARAM(pam_event->GetRunInfo()->RUNHEADER_TIME,206,dbc); // parameters stored in DB in GL_PRAM table
	if ( error<0 ) {
	  return(1);
	};
	//
	tofdedx->ReadParBBneg((glparam->PATH+glparam->NAME).Data());
	printf(" Reading BBneg file: %s \n",(glparam->PATH+glparam->NAME).Data());

	//
	error=glparam->Query_GL_PARAM(pam_event->GetRunInfo()->RUNHEADER_TIME,207,dbc); // parameters stored in DB in GL_PRAM table
	if ( error<0 ) {
	  return(1);
	};
	//
	tofdedx->ReadParBBpos((glparam->PATH+glparam->NAME).Data());
	printf(" Reading BBpos file: %s \n",(glparam->PATH+glparam->NAME).Data());

	//
	error=glparam->Query_GL_PARAM(pam_event->GetRunInfo()->RUNHEADER_TIME,208,dbc); // parameters stored in DB in GL_PRAM table
	if ( error<0 ) {
	  return(1);
	};
	//
	tofdedx->ReadParDesatBB((glparam->PATH+glparam->NAME).Data());
	printf(" Reading desaturation2 file: %s \n",(glparam->PATH+glparam->NAME).Data());
	
	tofdedx->CheckConnectors(pam_event->GetRunInfo()->RUNHEADER_TIME,glparam,dbc);
	
	
	error=glparam->Query_GL_PARAM(pam_event->GetRunInfo()->RUNHEADER_TIME,201,dbc); // parameters stored in DB in GL_PRAM table
	if ( error<0 ) {
	  return(1);
	};
	//
	printf(" Reading ToF parameter file: %s \n",(glparam->PATH+glparam->NAME).Data());
	//
	if ( (UInt_t)glparam->TO_TIME != (UInt_t)4294967295UL ) defcal = false;
	//
	TString pippo=(glparam->PATH+glparam->NAME).Data();
	//Int_t nlen = (Int_t)(glparam->PATH+glparam->NAME).Length();
	//rdtofcal((char *)(glparam->PATH+glparam->NAME).Data(),&nlen);
	Int_t nlen = (Int_t)pippo.Length();
        rdtofcal(pippo.Data(),&nlen);
	//

        tofdedx->Clear();

      };      
      //


      //================================================================
      //==================================================================
      //---  Define absolute time
      UInt_t tabs=pam_event->GetOrbitalInfo()->absTime;
      
      if ( !(iev%100000) ) printf(" ATIME %u re %u \n",(Int_t)tabs,(UInt_t)iev);

      //==================================================================
      Float_t dedx_corr_m[2000][48];//,dedx_corr[48];
      Double_t mtime[2000],t1,t2,tm;
      //      Float_t yhelp1,yhelp2,slope,inter,thelp1,thelp2;
      Float_t yhelp1,yhelp2;
      Float_t xmean1,xwidth1;

      Int_t ical=0;
      Int_t ii,j,jj;

      if (iev==0) {

	ical=0;  // counter set to zero if first-time reading

	//-----------------------------------------------------------
	// Here I  read the dEdx_korr parameters
	//-----------------------------------------------------------

	jj=0;
	printf(" READING NEW CALIBRATION FILE: %s \n",CALIBF.Data());

	ifstream fin(CALIBF.Data());
	//cout << "topolino" << endl;
	while (! fin.eof()) {
	  fin>>t1>>tm>>t2;
	  //cout<<jj<<" "<<tm<<endl;
	  //cout << setiosflags(ios::fixed)  << setw(10) << setprecision(3) << tm << endl;
	  mtime[jj]=tm;
	  for (ii=0; ii<48;ii++) {
	    fin>>j>>xmean1>>xwidth1;
	    dedx_corr_m[jj][ii]=xmean1;
	  }
	  jj=jj+1;
	  //	  printf(" kk %i \n",jj);
	}
	//	printf(" 1ical %i \n",ical);
	//cout << "pippo" << endl;
	fin.close();


	while (tabs<mtime[ical] || tabs > mtime[ical+1]) {
	  //	  printf(" ical %i \n",ical);
	  ical = ical+1;
	}
	//	ical = ical-1;
	//cout<<"abs time "<<tabs<<" limit low "<<mtime[ical]<<" limit up "<<mtime[ical+1]<<" ical "<<ical<<endl;
      } // if iev==0...

      //==================================================================
      //==  End of first time reading & filling the array
      //==================================================================

      //==================================================================
      //==  if time is outside time limits: 
      //==================================================================

      if (tabs<mtime[ical] || tabs>mtime[ical+1]) {
	cout<<"Checking Time Limits!"<<endl;
	ical=0;
	while (tabs > mtime[ical+1] || tabs<mtime[ical]) {
	  ical = ical+1;
	}
	//	ical = ical-1;
	//cout<<"abs time "<<tabs<<" limit low "<<mtime[ical]<<" limit up "<<mtime[ical+1]<<" ical "<<ical<<endl;
      };

      //      printf(" 2ical %i \n",ical);
      //==================================================================
      //== interpolate betwen time limits
      //==================================================================

      //      thelp1 = mtime[ical];
      //      thelp2 = mtime[ical+1];

      for (ii=0; ii<48;ii++) {
	yhelp1 = fabs(dedx_corr_m[ical][ii]);
	//	yhelp1 = 6.;
	if ( yhelp1 < 0.1 ) yhelp1 = 4.;
	yhelp2 = fabs(dedx_corr_m[ical+1][ii]);
	//	yhelp2 = 6.;
	if ( yhelp2 < 0.1 ) yhelp2 = 4.;
        //	slope  = (yhelp2-yhelp1)/(thelp2-thelp1);
        //	inter  = yhelp1 - slope*thelp1;
        //	dedx_corr[ii] = slope*tabs + inter;
	//       if (ii==0) cout<<thelp1<<" "<<thelp2<<" "<<tabs<<" "<<yhelp1<<" "<<yhelp2<<" "<<dedx_corr[0]<<endl;
      }

      //================================================================
      //================================================================
      //      printf("cpippo \n");

      // process tof data
      //
      for (Int_t hh=0; hh<12;hh++){
        for (Int_t kk=0; kk<4;kk++){
	  adc[kk][hh] = 4095;
	  tdc[kk][hh] = 4095;
	  tdcc[kk][hh] = 4095.;
	  tofinput_.adc[hh][kk] = 4095;
	  tofinput_.tdc[hh][kk] = 4095;
	};
      };
      //      memset(adc, 0, 12*4*sizeof(Int_t));
      //      memset(tdc, 0, 12*4*sizeof(Int_t));
      Int_t gg = 0;
      Int_t hh = 0;
      Int_t adcf[48];
      memset(adcf, 0, 48*sizeof(Int_t));
      Int_t tdcf[48];
      memset(tdcf, 0, 48*sizeof(Int_t));
      for (Int_t pm=0; pm < tofl2->ntrk() ; pm++){
	ToFTrkVar *ttf = tofl2->GetToFTrkVar(pm);
	for ( Int_t nc=0; nc < ttf->npmttdc; nc++){
	  if ( (ttf->tdcflag).At(nc) != 0 ) tdcf[(ttf->pmttdc).At(nc)] = 1;
	};
	for ( Int_t nc=0; nc < ttf->npmtadc; nc++){
	  if ( (ttf->adcflag).At(nc) != 0 ) adcf[(ttf->pmtadc).At(nc)] = 1;
	};
      };
      //
      for (Int_t pm=0; pm < tofl2->npmt() ; pm++){
	ToFPMT *pmt = tofl2->GetToFPMT(pm);
	tofl2->GetPMTIndex(pmt->pmt_id, gg, hh);
	if ( adcf[pmt->pmt_id] == 0 ){
	  tofinput_.adc[gg][hh] = (int)pmt->adc;
	  adc[hh][gg] = (int)pmt->adc;
	};
	if ( tdcf[pmt->pmt_id] == 0 ){
	  tofinput_.tdc[gg][hh] = (int)pmt->tdc;
	  tdc[hh][gg] = (int)pmt->tdc;
	};
	tdcc[hh][gg] = (float)pmt->tdc_tw;
	//        Int_t pppid = tof->GetPMTid(hh,gg);
	//	printf(" pm %i pmt_id %i pppid %i hh %i gg %i tdcc %f tdc %f adc %f \n",pm,pmt->pmt_id,pppid,hh,gg,pmt->tdc_tw,pmt->tdc,pmt->adc);
      };
      for (Int_t hh=0; hh<12;hh++){
        for (Int_t kk=0; kk<4;kk++){      
	  tofdedx->Init(kk,hh,adc[kk][hh]);
	};
      };
      //      for (Int_t pm=0; pm <48 ; pm++){
      //	tof->GetPMTIndex(pm, gg, hh);
      //	tofinput_.tdc[hh][gg] = (int)500.;
      //	tofinput_.adc[hh][gg] = (int)500.;
      //	tdc[hh][gg] = (int)500.;
      //	adc[hh][gg] = (int)500.;
      //	//	printf(" hh %i gg %i tdc %f adc %f \n",hh,gg,pmt->tdc,pmt->adc);
      //    };
      //
      for (Int_t hh=0; hh<5;hh++){
	tofinput_.patterntrig[hh]=pam_event->GetTrigLevel2()->patterntrig[hh];
      };	    
      //
      tof->Clear();
      Int_t pmt_id = 0;
      ToFPMT *t_pmt = new ToFPMT();
      if(!(tof->PMT))tof->PMT = new TClonesArray("ToFPMT",12); //ELENA
      TClonesArray &tpmt = *tof->PMT;
      ToFTrkVar *t_tof = new ToFTrkVar();
      if(!(tof->ToFTrk))tof->ToFTrk = new TClonesArray("ToFTrkVar",2); //ELENA  	 
      TClonesArray &t = *tof->ToFTrk;
      //
      //
      // Here we have calibrated data, ready to be passed to the FORTRAN routine which will extract common and track-related  variables.
      //
      npmtentry = 0;
      //
      ntrkentry = 0;
      //
      // Calculate tracks informations from ToF alone
      //
      tofl2com();
      //
      memcpy(tof->tof_j_flag,tofoutput_.tof_j_flag,6*sizeof(Int_t));
      //
      t_tof->trkseqno = -1;
      //
      // and now we must copy from the output structure to the level2 class:
      //
      t_tof->npmttdc = 0;
      //
      for (Int_t hh=0; hh<12;hh++){
	for (Int_t kk=0; kk<4;kk++){
	  if ( tofoutput_.tofmask[hh][kk] != 0 ){
	    pmt_id = tof->GetPMTid(kk,hh);
	    t_tof->pmttdc.AddAt(pmt_id,t_tof->npmttdc);
	    t_tof->tdcflag.AddAt(tofoutput_.tdcflagtof[hh][kk],t_tof->npmttdc); // gf: Jan 09/07
	    t_tof->npmttdc++;
	  };
	};
      };
      for (Int_t kk=0; kk<13;kk++){
	t_tof->beta[kk] = tofoutput_.betatof_a[kk];	
      }
      //
      memcpy(t_tof->xtofpos,tofoutput_.xtofpos,sizeof(t_tof->xtofpos));
      memcpy(t_tof->ytofpos,tofoutput_.ytofpos,sizeof(t_tof->ytofpos));
      memcpy(t_tof->xtr_tof,tofoutput_.xtr_tof,sizeof(t_tof->xtr_tof));
      memcpy(t_tof->ytr_tof,tofoutput_.ytr_tof,sizeof(t_tof->ytr_tof));
      //      {	
// 	Float_t xtof_temp[6]={0.,t_tof->xtofpos[0],t_tof->xtofpos[1],0.,0.,t_tof->xtofpos[2]};
// 	Float_t ytof_temp[6]={t_tof->ytofpos[0],0.,0.,t_tof->ytofpos[1],t_tof->ytofpos[2],0.};
// 	tofdedx->Process(pam_event->GetOrbitalInfo()->absTime,t_tof->beta[12], (Float_t *)xtof_temp,(Float_t *)ytof_temp);
//       }
//       t_tof->npmtadc = 0;


//       for (Int_t hh=0; hh<12;hh++){
// 	for (Int_t kk=0; kk<4;kk++){
// 	  pmt_id = tof->GetPMTid(kk,hh);
// 	  if ( tofdedx->GetdEdx_pmt(pmt_id)>-1. ){
// 	    t_tof->dedx.AddAt((tofdedx->GetdEdx_pmt(pmt_id)*36./pow(dedx_corr[pmt_id],2)),t_tof->npmtadc);
// 	    t_tof->pmtadc.AddAt(pmt_id,t_tof->npmtadc);
// 	    t_tof->adcflag.AddAt(0,t_tof->npmtadc); // gf: Jan 09/07
// 	    t_tof->npmtadc++;
// 	  };
// 	};
//       };
     {

	Float_t xtof_temp[6]={100.,100.,100.,100.,100.,100.};
	Float_t ytof_temp[6]={100.,100.,100.,100.,100.,100.};

	if(t_tof->xtofpos[0]<100. && t_tof->ytofpos[0]<100.){
	  xtof_temp[1]=t_tof->xtofpos[0];
	  ytof_temp[0]=t_tof->ytofpos[0];
	}else if(t_tof->xtofpos[0]>=100. && t_tof->ytofpos[0]<100.){
	  ytof_temp[0]=t_tof->ytofpos[0];
	  tof->GetPaddleGeometry(0,(Int_t)log2(tof->tof_j_flag[0]),xleft, xright, yleft, yright);
	  xtof_temp[1]=xleft+2.55;
	}else if(t_tof->ytofpos[0]>=100. && t_tof->xtofpos[0]<100.){
	  xtof_temp[1]=t_tof->xtofpos[0];
	  tof->GetPaddleGeometry(1,(Int_t)log2(tof->tof_j_flag[1]),xleft, xright, yleft, yright);
	  ytof_temp[0]=yleft+2.75;
	}

	if(t_tof->xtofpos[1]<100. && t_tof->ytofpos[1]<100.){
	  xtof_temp[2]=t_tof->xtofpos[1];
	  ytof_temp[3]=t_tof->ytofpos[1];
	}else if(t_tof->xtofpos[1]>=100. && t_tof->ytofpos[1]<100.){
	  ytof_temp[3]=t_tof->ytofpos[1];
	  tof->GetPaddleGeometry(3,(Int_t)log2(tof->tof_j_flag[3]),xleft, xright, yleft, yright);
	  xtof_temp[2]=xleft+4.5;
	}else if(t_tof->ytofpos[1]>=100. && t_tof->xtofpos[1]<100.){
	  xtof_temp[2]=t_tof->xtofpos[1];
	  tof->GetPaddleGeometry(2,(Int_t)log2(tof->tof_j_flag[2]),xleft, xright, yleft, yright);
	  ytof_temp[3]=yleft+3.75;
	}

	if(t_tof->xtofpos[2]<100. && t_tof->ytofpos[2]<100.){
	  xtof_temp[5]=t_tof->xtofpos[2];
	  ytof_temp[4]=t_tof->ytofpos[2];
	}else if(t_tof->xtofpos[2]>=100. && t_tof->ytofpos[2]<100.){
	  ytof_temp[4]=t_tof->ytofpos[2];
	  tof->GetPaddleGeometry(4,(Int_t)log2(tof->tof_j_flag[4]),xleft, xright, yleft, yright);
	  xtof_temp[5]=xleft+3;
	}else if(t_tof->ytofpos[2]>=100. && t_tof->xtofpos[2]<100.){
	  xtof_temp[5]=t_tof->xtofpos[2];
	  tof->GetPaddleGeometry(5,(Int_t)log2(tof->tof_j_flag[5]),xleft, xright, yleft, yright);
	  ytof_temp[4]=yleft+2.5;
	}
//       Float_t xtof_temp[6]={0.,t_tof->xtofpos[0],t_tof->xtofpos[1],0.,0.,t_tof->xtofpos[2]};
//       Float_t ytof_temp[6]={t_tof->ytofpos[0],0.,0.,t_tof->ytofpos[1],t_tof->ytofpos[2],0.};
//	tofdedx->Process(atime,t_tof->beta[12], (Float_t *)xtof_temp,(Float_t *)ytof_temp);
        tofdedx->Process(pam_event->GetOrbitalInfo()->absTime,t_tof->beta[12], (Float_t *)xtof_temp,(Float_t *)ytof_temp);
	t_tof->npmtadc = 0;
	for (Int_t hh=0; hh<12;hh++){
	  for (Int_t kk=0; kk<4;kk++){
	    pmt_id = tof->GetPMTid(kk,hh);
	    Int_t Iplane=-1;
	    Int_t Ipaddle=-1;
	    //	    Int_t IpaddleT=-1;
	    tof->GetPMTPaddle(pmt_id, Iplane, Ipaddle);
	    tof->GetPaddleGeometry(Iplane,Ipaddle,xleft,xright,yleft,yright);
	    if ( tofdedx->GetdEdx_pmt(pmt_id)>-1. &&((xtof_temp[Iplane]>=xleft&&xtof_temp[Iplane]<=xright) || (ytof_temp[Iplane]>=yleft&&ytof_temp[Iplane]<=yright)) ){  //attenzione:qui va inserito un controllo sulla traccia tof o sulle variabili di posizione !!!!
	      //t_tof->dedx.AddAt((tofdedx->GetdEdx_pmt(pmt_id)*4./dedx_corr[pmt_id]),t_tof->npmtadc);
	      //t_tof->dedx.AddAt((tofdedx->GetdEdx_pmt(pmt_id)*dedx_corr[pmt_id]/4.),t_tof->npmtadc);//annullo wolfrizzazione
	      t_tof->dedx.AddAt((tofdedx->GetdEdx_pmt(pmt_id)),t_tof->npmtadc);//annullo wolfrizzazione
	      t_tof->pmtadc.AddAt(pmt_id,t_tof->npmtadc);
	      t_tof->adcflag.AddAt(0,t_tof->npmtadc); // gf: Jan 09/07
	      t_tof->npmtadc++;
	    };
	  };
	};
      };









     
     //       for (Int_t hh=0; hh<12;hh++){
     // 	for (Int_t kk=0; kk<4;kk++){
     //           if ( tofoutput_.adctof_c[hh][kk] < 1000 ){
     // 	    //	    t_tof->dedx.AddAt(tofoutput_.adctof_c[hh][kk],t_tof->npmtadc); // EMILIANO
     // 	    pmt_id = tof->GetPMTid(kk,hh); 
     // 	    t_tof->dedx.AddAt((tofoutput_.adctof_c[hh][kk]*4./dedx_corr[pmt_id]),t_tof->npmtadc); // EMILIANO
     // 	    t_tof->pmtadc.AddAt(pmt_id,t_tof->npmtadc);
     // 	    t_tof->adcflag.AddAt(tofoutput_.adcflagtof[hh][kk],t_tof->npmtadc); // gf: Jan 09/07
     // 	    t_tof->npmtadc++;
     // 	  };
     // 	};
     //       };
     //
     
     //
     new(t[ntrkentry]) ToFTrkVar(*t_tof);
     ntrkentry++;	
     t_tof->Clear();
     //
     //
     //
     t_pmt->Clear();
     //
      for (Int_t hh=0; hh<12;hh++){
	for (Int_t kk=0; kk<4;kk++){
	  // new WM
	  //	  if ( tofoutput_.tdc_c[hh][kk] < 4095 || adc[kk][hh] < 4095  || tdc[kk][hh] < 4095 ){	   
	  if ( tdcc[kk][hh] < 4095. || adc[kk][hh] < 4095  || tdc[kk][hh] < 4095 ){	   
	    //
	    t_pmt->pmt_id = tof->GetPMTid(kk,hh);
	    t_pmt->tdc_tw = tofoutput_.tdc_c[hh][kk];
	    t_pmt->adc = (Float_t)adc[kk][hh];
	    t_pmt->tdc = (Float_t)tdc[kk][hh];
            //
	    new(tpmt[npmtentry]) ToFPMT(*t_pmt);
	    npmtentry++;	
	    t_pmt->Clear();
	  };
	};
      };      
      //
      // Calculate track-related variables 
      //
      if ( pam_event->GetTrkLevel2()->ntrk() > 0 ){
	//
	// We have at least one track
	//
	//
	// Run over tracks
	//
	for(Int_t nt=0; nt < pam_event->GetTrkLevel2()->ntrk(); nt++){  
	  //
	  TrkTrack *ptt = pam_event->GetTrkLevel2()->GetStoredTrack(nt); 
	  //
	  // Copy the alpha vector in the input structure
	  //
	  for (Int_t e = 0; e < 5 ; e++){
	    tofinput_.al_pp[e] = ptt->al[e];
	  };	  

	  // new input for 9th reduction: tracker dEdx
          tofinput_.trkmip = ptt->GetDEDX();

	  //
	  // Get tracker related variables for this track
	  //
	  toftrk();
	  //	  toftrk(thelp);
	  //
	  // Copy values in the class from the structure (we need to use a temporary class to store variables).
	  //
	  t_tof->npmttdc = 0;
	  for (Int_t hh=0; hh<12;hh++){
	    for (Int_t kk=0; kk<4;kk++){
	      if ( tofoutput_.tofmask[hh][kk] != 0 ){
		pmt_id = tof->GetPMTid(kk,hh);
		t_tof->pmttdc.AddAt(pmt_id,t_tof->npmttdc);
		t_tof->tdcflag.AddAt(tofoutput_.tdcflag[hh][kk],t_tof->npmttdc); // gf: Jan 09/07
		t_tof->npmttdc++;
	      };
	    };
	  };
	  for (Int_t kk=0; kk<13;kk++){
	    t_tof->beta[kk] = tofoutput_.beta_a[kk];	
	  };
	  //
	  memcpy(t_tof->xtofpos,tofoutput_.xtofpos,sizeof(t_tof->xtofpos));
	  memcpy(t_tof->ytofpos,tofoutput_.ytofpos,sizeof(t_tof->ytofpos));
	  memcpy(t_tof->xtr_tof,tofoutput_.xtr_tof,sizeof(t_tof->xtr_tof));
	  memcpy(t_tof->ytr_tof,tofoutput_.ytr_tof,sizeof(t_tof->ytr_tof));
	  //
	  tofdedx->Process(pam_event->GetOrbitalInfo()->absTime,t_tof->beta[12], (Float_t *)t_tof->xtr_tof,(Float_t *)t_tof->ytr_tof);
	  t_tof->npmtadc = 0;

	  for (Int_t hh=0; hh<12;hh++){
	    for (Int_t kk=0; kk<4;kk++){
	      pmt_id = tof->GetPMTid(kk,hh);
	      Int_t Iplane=-1;
	      Int_t Ipaddle=-1;
	      Int_t IpaddleT=-1;
	      tof->GetPMTPaddle(pmt_id, Iplane, Ipaddle);
	      IpaddleT=tof->GetPaddleIdOfTrack(t_tof->xtr_tof[Iplane],t_tof->ytr_tof[Iplane], Iplane,0.0);
	      if ( tofdedx->GetdEdx_pmt(pmt_id) > -1. && Ipaddle==IpaddleT ){ 
		//t_tof->dedx.AddAt((tofdedx->GetdEdx_pmt(pmt_id)*4./dedx_corr[pmt_id]),t_tof->npmtadc);
		//t_tof->dedx.AddAt((tofdedx->GetdEdx_pmt(pmt_id)*dedx_corr[pmt_id]/4.),t_tof->npmtadc);//annullo wolfrizzazione
		t_tof->dedx.AddAt((tofdedx->GetdEdx_pmt(pmt_id)),t_tof->npmtadc);//annullo wolfrizzazione
		t_tof->pmtadc.AddAt(pmt_id,t_tof->npmtadc);
		t_tof->adcflag.AddAt(0,t_tof->npmtadc); // gf: Jan 09/07
		t_tof->npmtadc++;
	      };
	      
	    };
	  };


// 	  for (Int_t hh=0; hh<12;hh++){
// 	    for (Int_t kk=0; kk<4;kk++){
// 	      pmt_id = tof->GetPMTid(kk,hh);
// 	      if ( tofdedx->GetdEdx_pmt(pmt_id) > -1. ){
// 		t_tof->dedx.AddAt((tofdedx->GetdEdx_pmt(pmt_id)*36./pow(dedx_corr[pmt_id],2)),t_tof->npmtadc);
// 		t_tof->pmtadc.AddAt(pmt_id,t_tof->npmtadc);
// 		t_tof->adcflag.AddAt(0,t_tof->npmtadc); // gf: Jan 09/07
// 		printf(" nt %i npmtadc %i dedx %f dedx corr %f\n",nt,t_tof->npmtadc,(tofdedx->GetdEdx_pmt(pmt_id)*36./pow(dedx_corr[pmt_id],2)),dedx_corr[pmt_id]);
// 		t_tof->npmtadc++;
// 	      };
	      
// 	    };
// 	  };
// 	  t_tof->npmtadc = 0;
// 	  for (Int_t hh=0; hh<12;hh++){
// 	    for (Int_t kk=0; kk<4;kk++){
// 	      if ( tofoutput_.adc_c[hh][kk] < 1000 ){
// 		//	    t_tof->dedx.AddAt(tofoutput_.adc_c[hh][kk],t_tof->npmtadc); // EMILIANO
// 	        pmt_id = tof->GetPMTid(kk,hh); 
//   	        t_tof->dedx.AddAt((tofoutput_.adc_c[hh][kk]*4./dedx_corr[pmt_id]),t_tof->npmtadc); // EMILIANO
// 		t_tof->pmtadc.AddAt(pmt_id,t_tof->npmtadc);
// 		t_tof->adcflag.AddAt(tofoutput_.adcflag[hh][kk],t_tof->npmtadc); // gf: Jan 09/07
// 		t_tof->npmtadc++;
// 	      };
// 	    };
// 	  };
	  //

	  //
	  // Store the tracker track number in order to be sure to have shyncronized data during analysis
	  //
	  t_tof->trkseqno = nt;
	  //
	  // create a new object for this event with track-related variables
	  //
	  new(t[ntrkentry]) ToFTrkVar(*t_tof);
	  ntrkentry++;	
	  t_tof->Clear();
	  //
	}; // loop on all the tracks
      }; 
      //
      tof->unpackError = tofl2->unpackError;
      if ( defcal ){
	tof->default_calib = 1;
      } else {
	tof->default_calib = 0;
      };
      //
      // Fill the rootple 
      //
      toft->Fill();
      //    
      //	toft->Show();
      //	toftr->Show();
      //
      delete t_tof;
      //
      //
    };
    //
  };
  //
  pam_event->Clear();
  //
  outft->cd();
  pam_event->WriteCloneTrees();
  toftr->Delete();

  toft->Write();
  outft->Close();
  //
  return 0;
  //  
}

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

#if !defined(__CINT__) 

void usage(){

  cout << "------------------------------------------------------------"<<endl;
  cout << "Loop over events (on one or more Level2-files), applying some selection cuts (defined in My-Selection.cpp), \n";
  cout << "creating output histograms (defined in My-Histos.cpp) and/or trees with selected events. \n \n ";
  cout << "USAGE:"<<endl;
  cout << "-processDir  DIR     -  Level2 data directory \n";
  cout << "-processList LIST    -  list  of files (.txt) or single file (.root) to be analysed \n";
  cout << "-outputFile  PATH    -  name of the output file \n";
  cout << "-calibFile PATH+NAME -  name of the calibration file \n";
  cout << "-NumEvents   XXX     -  number of events to be analysed \n";
  cout << "--debug, -g          -  debug mode \n";
  cout << "--help, -h           -  print this help \n";
  cout << "-options [ options ] -  options: \n";
  cout << "                        fillHistos --> create an output file with histograms  \n";
  cout << "                        fillTree   --> create an output file with trees storing the selected events \n ";
  cout << "                        +(-)ALL    --> inlcude(exclude) all trees and branches \n "   ;
  cout << "                        +(-)TRK1 +(-)TRK2 +(-)CAL1 +(-)CAL2 +(-)TOF +(-)TRG +(-)ND +(-)S4 +(-)ORB --> inlcude(exclude) trees and branches  \n"  ; 
  cout << "------------------------------------------------------------"<<endl;
}
//
int HandleInputPar(int argc, char **argv){

  if(argc>1){
		
    if(!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help") ){
      usage();
      return(1);
    };
    // -----------------------
    // Read input parameters
    // -----------------------  
    DIR     = gSystem->WorkingDirectory();
    LIST    = "";
    OUTF    = "myfile";
    OPTIONS = "+AUTO -TOF";
		
    for (int i = 1; i < argc; i++){		
      // -----------------------------------------------------//
      if (!strcmp(argv[i], "-processDir")){
	if (++i >= argc) throw -1;
	DIR = argv[i];
	cout << "processDir "<<DIR<<endl;
	continue;
      }
      // -----------------------------------------------------//
      else if (!strcmp(argv[i], "-processList")){
	if (++i >= argc) throw -1;
	LIST = argv[i];
	cout << "processList "<<LIST<<endl;
	continue;
      }  
      // -----------------------------------------------------//
      else if (!strcmp(argv[i], "-outputFile")){
	if (++i >= argc) throw -1;
	OUTF = argv[i];
	cout << "outputFile "<<OUTF<<endl;
	continue;
      }  
      // -----------------------------------------------------//
      // -----------------------------------------------------//
      else if (!strcmp(argv[i], "-calibFile")){
	if (++i >= argc) throw -1;
	CALIBF = gSystem->ExpandPathName(argv[i]);
	cout << "calibFile "<<CALIBF<<endl;
	continue;
      }  
      // -----------------------------------------------------//
      else if (!strcmp(argv[i], "-options")){
	if (++i >= argc) throw -1;
	OPTIONS = argv[i];
	if( OPTIONS.Contains("[") ){
	  do{
	    if (++i >= argc) throw -1;
	    OPTIONS.Append(argv[i]);
	  }while(!OPTIONS.Contains("]"));
	}else cout << "wrong option format --> ignoring " << endl;
      }
      else{
	cout << "Unidentified input parameter. Ignored."<< endl;
      };
    };
  }else{
    usage();
    return(1);
  };
  // -----------------------
  // Check input parameters
  // -----------------------  
	
		
  return(0);
	
};
// 

int main(int argc, char **argv)
{
	
  if( HandleInputPar(argc,argv) )return(1);
	
  cout << "OPTIONS "<<OPTIONS<<endl;
  Loop(DIR,LIST,OPTIONS);
    
  cout << "Back to main - end"<<endl;
    
  return 0;
	
};

#endif
