/**
 * \file ToFLevel2.cpp
 * \author Gianfranca DeRosa, Wolfgang Menn
 */

#include <TObject.h>
#include <ToFLevel2.h>
#include <iostream>
using namespace std;
ClassImp(ToFPMT);
ClassImp(ToFTrkVar);
ClassImp(ToFLevel2);

ToFPMT::ToFPMT(){
  pmt_id = 0;
  adc = 0.;
  tdc_tw = 0.;
}

ToFPMT::ToFPMT(const ToFPMT &t){
  pmt_id = t.pmt_id;
  adc = t.adc;
  tdc_tw = t.tdc_tw;
}

void ToFPMT::Clear(){
  pmt_id = 0;
  adc = 0.;
  tdc_tw = 0.;
}



ToFTrkVar::ToFTrkVar() {
  trkseqno = 0;
  npmttdc = 0;
  npmtadc = 0;
  pmttdc = TArrayI(48);
  pmtadc = TArrayI(48);
  tdcflag = TArrayI(48); // gf: 30 Nov 2006
  adcflag = TArrayI(48); // gf: 30 Nov 2006
  dedx = TArrayF(48);
  //
  //
  memset(beta,  0, 13*sizeof(Float_t));
  memset(xtofpos,  0, 3*sizeof(Float_t));
  memset(ytofpos,  0, 3*sizeof(Float_t));
  memset(xtr_tof,  0, 6*sizeof(Float_t));
  memset(ytr_tof,  0, 6*sizeof(Float_t));
  //
};

void ToFTrkVar::Clear() {
  trkseqno = 0;
  npmttdc = 0;
  npmtadc = 0;
  pmttdc.Reset();
  pmtadc.Reset();
  tdcflag.Reset(); // gf: 30 Nov 2006
  adcflag.Reset(); // gf: 30 Nov 2006
  dedx.Reset(); 
  //
  memset(beta,  0, 13*sizeof(Float_t));
  memset(xtofpos,  0, 3*sizeof(Float_t));
  memset(ytofpos,  0, 3*sizeof(Float_t));
  memset(xtr_tof,  0, 6*sizeof(Float_t));
  memset(ytr_tof,  0, 6*sizeof(Float_t));
  //
};

ToFTrkVar::ToFTrkVar(const ToFTrkVar &t){

  trkseqno = t.trkseqno;  
  //
  npmttdc = t.npmttdc;
  npmtadc = t.npmtadc;
  (t.pmttdc).Copy(pmttdc);
  (t.pmtadc).Copy(pmtadc);
  (t.tdcflag).Copy(tdcflag); // gf: 30 Nov 2006
  (t.adcflag).Copy(adcflag); // gf: 30 Nov 2006
  (t.dedx).Copy(dedx);
  //
  memcpy(beta,t.beta,sizeof(beta));
  memcpy(xtofpos,t.xtofpos,sizeof(xtofpos));
  memcpy(ytofpos,t.ytofpos,sizeof(ytofpos));
  memcpy(xtr_tof,t.xtr_tof,sizeof(xtr_tof));
  memcpy(ytr_tof,t.ytr_tof,sizeof(ytr_tof));
  //
};

ToFLevel2::ToFLevel2() {    
  //
//  PMT = new TClonesArray("ToFPMT",12); //ELENA
//  ToFTrk = new TClonesArray("ToFTrkVar",2); //ELENA
  PMT = 0; //ELENA
  ToFTrk = 0; //ELENA
  //
  this->Clear();
  //
};

void ToFLevel2::Set(){//ELENA
    if(!PMT)PMT = new TClonesArray("ToFPMT",12); //ELENA
    if(!ToFTrk)ToFTrk = new TClonesArray("ToFTrkVar",2); //ELENA
}//ELENA

void ToFLevel2::Clear(){
  //
  if(ToFTrk)ToFTrk->Delete(); //ELENA
  if(PMT)PMT->Delete(); //ELENA
  memset(tof_j_flag, 0, 6*sizeof(Int_t));
  unpackError = 0;
  // 
};

void ToFLevel2::Delete(){ //ELENA
  //
  if(ToFTrk){ 
      ToFTrk->Delete(); //ELENA
      delete ToFTrk;  //ELENA
  }
  if(PMT){
      PMT->Delete(); //ELENA
      delete PMT; //ELENA
  } //ELENA
  // 
}; //ELENA

ToFTrkVar *ToFLevel2::GetToFTrkVar(Int_t itrk){
  //    
  if(itrk >= ntrk()){
    printf(" ToFLevel2 ERROR: track related variables set %i does not exists! \n",itrk);
    printf("                      stored track related variables = %i \n",ntrk());
    return(NULL);
  }  
  //
  if(!ToFTrk)return 0; //ELENA
  TClonesArray &t = *(ToFTrk);
  ToFTrkVar *toftrack = (ToFTrkVar*)t[itrk];
  return toftrack;
}

ToFPMT *ToFLevel2::GetToFPMT(Int_t ihit){
  //    
  if(ihit >= npmt()){
    printf(" ToFLevel2 ERROR: pmt variables set %i does not exists! \n",ihit);
    printf("                  stored pmt variables = %i \n",npmt());
    return(NULL);
  }  
  //
  if(!PMT)return 0; //ELENA
  TClonesArray &t = *(PMT);
  ToFPMT *tofpmt = (ToFPMT*)t[ihit];
  return tofpmt;
}
//--------------------------------------
//
// 
//--------------------------------------
/**
 * Method to get the plane ID (11 12 21 22 31 32) from the plane index (0 1 2 3 4 5)
 * @param Plane index (0,1,2,3,4,5).
 */
  Int_t  ToFLevel2::GetToFPlaneID(Int_t ip){ 
      if(ip>=0 && ip<6)return 10*((int)(ip/2+1.1))+(ip%2)+1;
      else return -1;
  };
/**
 * Method to get the plane index (0 1 2 3 4 5) from the plane ID (11 12 21 22 31 32)
 * @param plane Plane ID (11, 12, 21, 22, 31, 32) 
 */
  Int_t  ToFLevel2::GetToFPlaneIndex(Int_t plane_id){ 
      if(
	 plane_id == 11 ||
	 plane_id == 12 ||
	 plane_id == 21 ||
	 plane_id == 22 ||
	 plane_id == 31 ||
	 plane_id == 32 ||
	 false)return (Int_t)(plane_id/10)*2-1- plane_id%2;
      else return -1;
  };
/**
 * Method to know if a given ToF paddle was hit, that is there is a TDC signal 
 * from both PMTs. The method uses the "tof_j_flag" variable.
 * @param plane Plane ID (11, 12, 21, 22, 31, 32) or Plane index (0,1,2,3,4,5).
 * @param paddle_id Paddle ID.
 * @return 1 if the paddle was hit.
 */
  Bool_t ToFLevel2::HitPaddle(Int_t plane, Int_t paddle_id){  //<<< NEW
    Int_t ip = -1;
    if     (plane>=6             ) ip = GetToFPlaneIndex(plane);
    else if(plane>=0 && plane < 6) ip = plane;
    Int_t flag=0;
    if(ip != -1)flag = tof_j_flag[ip] & (int)pow(2.,(double)paddle_id);
    if(
       (ip == 0 && paddle_id < 8 && flag) ||
       (ip == 1 && paddle_id < 6 && flag) ||
       (ip == 2 && paddle_id < 2 && flag) ||
       (ip == 3 && paddle_id < 2 && flag) ||
       (ip == 4 && paddle_id < 3 && flag) ||
       (ip == 5 && paddle_id < 3 && flag) ||
       false) return true;
    else return false;
};
/**
 * Method to get the number of hit paddles on a ToF plane.
 * @param plane Plane ID (11, 12, 21, 22, 31, 32) or Plane index (0,1,2,3,4,5).
 */
Int_t ToFLevel2::GetNHitPaddles(Int_t plane){
    Int_t npad=0;
    for(Int_t i=0; i<8; i++)npad = npad + (int)HitPaddle(plane,i);
    return npad;
};


//gf Apr 07
/**
 * Method to get the mean dEdx from a given ToF plane. This current version
 * is just summing up all PMT signals, which will not give proper results, 
 *  and needs a revision.
 * @param notrack Track Number
 * @param plane Plane index (0,1,2,3,4,5)
 * @param adcflag in the plane (100<-> independent of the adcflag; !=0&&!=100 <-> at least one PMT with adcflag!=0; )
 */
Float_t ToFLevel2::GetdEdx(Int_t notrack, Int_t plane, Int_t adcfl){

  Float_t dedx = 0.;
  Float_t PadEdx =0.;
  Int_t SatWarning;
  Int_t pad=-1;
  //
  ToFTrkVar *trk = GetToFTrkVar(notrack);
  if(!trk) return 0; //ELENA
  //
  for (Int_t ii=0; ii<GetNPaddle(plane); ii++){
    Int_t paddleid=ii;
    pad = GetPaddleid(plane,paddleid);
    GetdEdxPaddle(notrack, pad, adcfl, PadEdx, SatWarning);
    dedx += PadEdx; 
  };
  //
  return(dedx);
};

/**
 * Method to fill the ADC_C 4x12 matrix with the dEdx values and the TDC 4x12 matrix 
 * with the time-walk corrected TDC values.
 * @param notrack Track Number
 * @param adc  ADC_C matrix with dEdx values
 * @param tdc  TDC matrix
 */
void ToFLevel2::GetMatrix(Int_t notrack, Float_t adc[4][12], Float_t tdc[4][12]){
  //
  for (Int_t aa=0; aa<4;aa++){
    for (Int_t bb=0; bb<12;bb++){
      adc[aa][bb] = 1000.;
      tdc[aa][bb] = 4095.;
    };
  };
  //
  Int_t pmt_id = 0;
  Int_t hh = 0;
  Int_t kk = 0;
  //
  ToFTrkVar *trk = GetToFTrkVar(notrack);
  if(!trk)return; //ELENA
  //
  for (Int_t i=0; i<trk->npmtadc; i++){
    //
    pmt_id = (trk->pmtadc).At(i);
    //
    GetPMTIndex(pmt_id,hh,kk);
    adc[kk][hh] = (trk->dedx).At(i);   
    //
  };
  //
  for (Int_t i=0; i<npmt(); i++){
    //
    ToFPMT *pmt = GetToFPMT(i);
    if(!pmt)break; //ELENA
    //
    GetPMTIndex(pmt->pmt_id,hh,kk);
    //
    tdc[kk][hh] = pmt->tdc_tw;   
    //
  };
  //
  return;
};


/**
 * Method to get the plane index (0 - 5) for the PMT_ID as input
 * @param pmt_id  PMT_ID (0 - 47)
 */
Int_t ToFLevel2::GetPlaneIndex(Int_t pmt_id){
  TString pmtname = GetPMTName(pmt_id);
  pmtname.Resize(3);
  if ( !strcmp(pmtname,"S11") ) return(0);
  if ( !strcmp(pmtname,"S12") ) return(1);
  if ( !strcmp(pmtname,"S21") ) return(2);
  if ( !strcmp(pmtname,"S22") ) return(3);
  if ( !strcmp(pmtname,"S31") ) return(4);
  if ( !strcmp(pmtname,"S32") ) return(5);
  return(-1);
};


/**
 * Method to get the PMT_ID if the index (4,12) is given. We have 4 channels on
 * each of the 12 half-boards, this method decodes which PMT is cables to which 
 * channel.
 * @param hh Channel
 * @param kk HalfBoard
 */
Int_t ToFLevel2::GetPMTid(Int_t hh, Int_t kk){
  //
  short tof[4][24] = {
    {4, 4,  4,  4,  1,  1, 2, 2,  3,  3, 3, 3,  3,  3, 1, 1,  1,  1, 2, 3,  3, 3, 3,  4},
    {1, 3,  5,  7, 10, 12, 2, 4,  2,  4, 6, 8, 10, 12, 1, 5,  3,  9, 7, 9, 11, 1, 5,  9},
    {2, 2,  2,  2,  1,  1, 1, 1,  4,  4, 4, 4,  4,  4, 2, 1,  2,  1, 2, 2,  2, 3, 3,  4},
    {6, 8, 12, 10,  8,  6, 4, 2, 12, 10, 8, 6,  4,  2, 9, 7, 11, 11, 5, 3,  1, 3, 7, 11}
  };
  //
  Int_t ind = 0;
  Int_t k = 0;
  while (k < 24){
    Int_t j = 0;
    while (j < 2){
      Int_t ch = tof[2*j][k]     - 1;
      Int_t hb = tof[2*j + 1][k] - 1;      
      /* tofEvent->tdc[ch][hb] */      
      if( ch == hh && hb == kk ){	
	ind = 2*k + j;
	break;
      };
      j++;
    };
    k++;
  };
  return ind;
};


/**
 * Method to get the PMT index if the PMT ID is given. This method is the
 * "reverse" of method "GetPMTid"
 * @param ind  PMT_ID (0 - 47)
 * @param hb   HalfBoard
 * @param ch   Channel
 */
void ToFLevel2::GetPMTIndex(Int_t ind, Int_t &hb, Int_t &ch){
  //
  short tof[4][24] = {
    {4, 4,  4,  4,  1,  1, 2, 2,  3,  3, 3, 3,  3,  3, 1, 1,  1,  1, 2, 3,  3, 3, 3,  4},
    {1, 3,  5,  7, 10, 12, 2, 4,  2,  4, 6, 8, 10, 12, 1, 5,  3,  9, 7, 9, 11, 1, 5,  9},
    {2, 2,  2,  2,  1,  1, 1, 1,  4,  4, 4, 4,  4,  4, 2, 1,  2,  1, 2, 2,  2, 3, 3,  4},
    {6, 8, 12, 10,  8,  6, 4, 2, 12, 10, 8, 6,  4,  2, 9, 7, 11, 11, 5, 3,  1, 3, 7, 11}
  };
  //
  Int_t k = 0;
  while (k < 24){
    Int_t j = 0;
    while (j < 2){
      /* tofEvent->tdc[ch][hb] */            
      if( ind == 2*k + j ){
 	ch = tof[2*j][k]     - 1;
 	hb = tof[2*j + 1][k] - 1;      
	return;
      };
      j++;
    };
    k++;
  };
  return;
};




/// gf Apr 07

/**
 * Method to get the dEdx from a given ToF paddle.
 * @param notrack Track Number
 * @param Paddle index (0,1,...,23).
 * @param adcflag in the paddle (100<-> independent of the adcflag; !=0&&!=100 <-> at least one PMT with adcflag!=0; )
 * @param PadEdx dEdx from a given ToF paddle
 * @param SatWarning 1 if the PMT ios near saturation region (adcraw ~3000)
 */
void ToFLevel2::GetdEdxPaddle(Int_t notrack, Int_t paddleid, Int_t adcfl, Float_t &PadEdx, Int_t &SatWarning){

  PadEdx = 0.;
  SatWarning = 1000;

  Float_t dEdx[48] = {0};
  Int_t pmt_id = -1;
  Float_t adcraw[48];
  //
  ToFTrkVar *trk = GetToFTrkVar(notrack);
  if(!trk) return; //ELENA
  //

  Int_t pmtleft=-1;
  Int_t pmtright=-1;
  GetPaddlePMT(paddleid, pmtleft, pmtright);

  adcraw[pmtleft] = 4095;
  adcraw[pmtright] = 4095;

  
  for (Int_t jj=0; jj<npmt(); jj++){
    
    ToFPMT *pmt = GetToFPMT(jj);
    if(!pmt)break; //ELENA
    
    pmt_id = pmt->pmt_id;
    if(pmt_id==pmtleft){
      adcraw[pmtleft] = pmt->adc;
    }
    
    if(pmt_id==pmtright){
      adcraw[pmtright] = pmt->adc;
    }
  }
  
  for (Int_t i=0; i<trk->npmtadc; i++){

    if((trk->adcflag).At(i)==0 || adcfl==100){
      if((trk->pmtadc).At(i) == pmtleft)dEdx[pmtleft] = (trk->dedx).At(i);
      if((trk->pmtadc).At(i) == pmtright)dEdx[pmtright] = (trk->dedx).At(i);
    }else{ 
      if((trk->pmtadc).At(i) == pmtleft)dEdx[pmtleft] = 0.;
      if((trk->pmtadc).At(i) == pmtright)dEdx[pmtright] = 0.;
    }
  }

  if( adcraw[pmtleft] >3000 || adcraw[pmtright] >3000)SatWarning=1;
    
  if(dEdx[pmtleft]!=0 && dEdx[pmtright]!=0){
    PadEdx = (dEdx[pmtleft]+dEdx[pmtright])*0.5;
  }
  if(dEdx[pmtleft]==0 && dEdx[pmtright]!=0){
    PadEdx = dEdx[pmtright];
  }
  if(dEdx[pmtleft]!=0 && dEdx[pmtright]==0){
    PadEdx = dEdx[pmtleft];
  }
  
  return;
};
//


// gf Apr 07

/**
 * Method to get the PMT name (like "S11_1A") if the PMT_ID is given.
 * Indexes of corresponding  plane, paddle and  pmt are also given as output.
 * @param ind  PMT_ID (0 - 47)
 * @param iplane plane index (0 - 5)
 * @param ipaddle paddle index (relative to the plane)
 * @param ipmt pmt index (0(A), 1(B))
 */
TString ToFLevel2::GetPMTName(Int_t ind, Int_t &iplane, Int_t &ipaddle,Int_t &ipmt){
  
  TString pmtname = " ";
  
  TString photoS[48] = {
    "S11_1A", "S11_1B", "S11_2A", "S11_2B", "S11_3A", "S11_3B", "S11_4A",
    "S11_4B",
    "S11_5A", "S11_5B", "S11_6A", "S11_6B", "S11_7A", "S11_7B", "S11_8A",
    "S11_8B",
    "S12_1A", "S12_1B", "S12_2A", "S12_2B", "S12_3A", "S12_3B", "S12_4A",
    "S12_4B", "S12_5A",  "S12_5B", "S12_6A", "S12_6B",
    "S21_1A", "S21_1B", "S21_2A", "S21_2B",
    "S22_1A", "S22_1B", "S22_2A", "S22_2B",
    "S31_1A", "S31_1B", "S31_2A", "S31_2B", "S31_3A", "S31_3B",
    "S32_1A", "S32_1B", "S32_2A", "S32_2B", "S32_3A", "S32_3B"
  };
  
  
  pmtname = photoS[ind].Data();
  
  TString ss = pmtname(1,2);
  iplane  = (int)(atoi(ss.Data())/10)*2-3+atoi(ss.Data())%10;
  ss = pmtname(4);
  ipaddle = atoi(ss.Data())-1 ;
  if( pmtname.Contains("A") )ipmt=0;
  if( pmtname.Contains("B") )ipmt=1;
  
  return pmtname;
};
/**
 * Method to get the PMT name (like "S11_1A") if the PMT_ID is given
 * @param ind  PMT_ID (0 - 47)
 */
TString ToFLevel2::GetPMTName(Int_t ind){

  Int_t iplane  = -1;
  Int_t ipaddle = -1;
  Int_t ipmt    = -1;
  return GetPMTName(ind,iplane,ipaddle,ipmt);
  
};


// gf Apr 07
Int_t ToFLevel2::GetPaddleIdOfTrack(Float_t xtr, Float_t ytr, Int_t plane){

  Double_t xt,yt,xl,xh,yl,yh;
  
  Float_t tof11_x[8] = {-17.85,-12.75,-7.65,-2.55,2.55,7.65,12.75,17.85};
  Float_t tof12_y[6] = { -13.75,-8.25,-2.75,2.75,8.25,13.75};
  Float_t tof21_y[2] = { 3.75,-3.75};
  Float_t tof22_x[2] = { -4.5,4.5};
  Float_t tof31_x[3] = { -6.0,0.,6.0};
  Float_t tof32_y[3] = { -5.0,0.0,5.0};
  
  //  S11 8 paddles  33.0 x 5.1 cm
  //  S12 6 paddles  40.8 x 5.5 cm
  //  S21 2 paddles  18.0 x 7.5 cm
  //  S22 2 paddles  15.0 x 9.0 cm
  //  S31 3 paddles  15.0 x 6.0 cm
  //  S32 3 paddles  18.0 x 5.0 cm
  
  Int_t paddleidoftrack=-1;
  //
  
  //--- S11 ------
  
  if(plane==0){
    xt = xtr;
    yt = ytr;
    paddleidoftrack=-1;
    yl = -33.0/2. ;
    yh =  33.0/2. ;
    if ((yt>yl)&&(yt<yh)) {
      for (Int_t i1=0; i1<8;i1++){
	xl = tof11_x[i1] - (5.1-0.4)/2. ;
	xh = tof11_x[i1] + (5.1-0.4)/2. ;
	if ((xt>xl)&&(xt<xh))  paddleidoftrack=i1;
      }
    }
  }
  //      cout<<"S11  "<<paddleidoftrack[0]<<"\n";
  
  //--- S12 -------
  if(plane==1){
    xt = xtr;
    yt = ytr;
    paddleidoftrack=-1;
    xl = -40.8/2. ;
    xh =  40.8/2. ;
    
    if ((xt>xl)&&(xt<xh)) {
      for (Int_t i1=0; i1<6;i1++){
	yl = tof12_y[i1] - (5.5-0.4)/2. ;
	yh = tof12_y[i1] + (5.5-0.4)/2. ;
	if ((yt>yl)&&(yt<yh))  paddleidoftrack=i1;
      }
    }
  }
  
  //--- S21 ------

  if(plane==2){
    xt = xtr;
    yt = ytr;
    paddleidoftrack=-1;
    xl = -18./2. ;
    xh =  18./2. ;
    
    if ((xt>xl)&&(xt<xh)) {
      for (Int_t i1=0; i1<2;i1++){
	yl = tof21_y[i1] - (7.5-0.4)/2. ;
	yh = tof21_y[i1] + (7.5-0.4)/2. ;
	if ((yt>yl)&&(yt<yh))  paddleidoftrack=i1;
      }
    }
  }
  
  //--- S22 ------
  if(plane==3){
    xt = xtr;
    yt = ytr;
    paddleidoftrack=-1;
    yl = -15./2. ;
    yh =  15./2. ;
    
    if ((yt>yl)&&(yt<yh)) {
      for (Int_t i1=0; i1<2;i1++){
	xl = tof22_x[i1] - (9.0-0.4)/2. ;
	xh = tof22_x[i1] + (9.0-0.4)/2. ;
	if ((xt>xl)&&(xt<xh))  paddleidoftrack=i1;
      }
    }
  }  
  
  //--- S31 ------
  if(plane==4){
    xt = xtr;
    yt = ytr;
    paddleidoftrack=-1;
    yl = -15.0/2. ;
    yh =  15.0/2. ;
    
    if ((yt>yl)&&(yt<yh)) {
      for (Int_t i1=0; i1<3;i1++){
	xl = tof31_x[i1] - (6.0-0.4)/2. ;
	xh = tof31_x[i1] + (6.0-0.4)/2. ;
	if ((xt>xl)&&(xt<xh))  paddleidoftrack=i1;
      }
    }
  }  
  
  //---  S32 ------
  if(plane==5){
    xt = xtr;
    yt = ytr;
    paddleidoftrack=-1;
    xl = -18.0/2. ;
    xh =  18.0/2. ;
    
    if ((xt>xl)&&(xt<xh)) {
      for (Int_t i1=0; i1<3;i1++){
	yl = tof32_y[i1] - (5.0-0.4)/2. ;
	yh = tof32_y[i1] + (5.0-0.4)/2. ;
	if ((yt>yl)&&(yt<yh)) paddleidoftrack=i1;
      }
    }
  }
  
  return paddleidoftrack;

}  

//

// gf Apr 07

void ToFLevel2::GetPMTPaddle(Int_t pmt_id, Int_t &plane, Int_t &paddle){
  
  plane = GetPlaneIndex(pmt_id);

  if(plane == 0){
    if(pmt_id==0 || pmt_id==1)paddle=0;
    if(pmt_id==2 || pmt_id==3)paddle=1;
    if(pmt_id==4 || pmt_id==5)paddle=2;
    if(pmt_id==6 || pmt_id==7)paddle=3;
    if(pmt_id==8 || pmt_id==9)paddle=4;
    if(pmt_id==10 || pmt_id==11)paddle=5;
    if(pmt_id==12 || pmt_id==13)paddle=6;
    if(pmt_id==14 || pmt_id==15)paddle=7;
  }
  
  if(plane == 1){
    if(pmt_id==16 || pmt_id==17)paddle=0;
    if(pmt_id==18 || pmt_id==19)paddle=1;
    if(pmt_id==20 || pmt_id==21)paddle=2;
    if(pmt_id==22 || pmt_id==23)paddle=3;
    if(pmt_id==24 || pmt_id==25)paddle=4;
    if(pmt_id==26 || pmt_id==27)paddle=5;
  }
  
  if(plane == 2){
    if(pmt_id==28 || pmt_id==29)paddle=0;
    if(pmt_id==30 || pmt_id==31)paddle=1;
  }
  
  if(plane == 3){
    if(pmt_id==32 || pmt_id==33)paddle=0;
    if(pmt_id==34 || pmt_id==35)paddle=1;
  }
  
  if(plane == 4){
    if(pmt_id==36 || pmt_id==37)paddle=0;
    if(pmt_id==38 || pmt_id==39)paddle=1;
    if(pmt_id==40 || pmt_id==41)paddle=2;
  }
  
  if(plane == 5){
    if(pmt_id==42 || pmt_id==43)paddle=0;
    if(pmt_id==44 || pmt_id==45)paddle=1;
    if(pmt_id==46 || pmt_id==47)paddle=2;
  }
  return;
}

//

// gf Apr 07

void ToFLevel2::GetPaddlePMT(Int_t paddle, Int_t &pmtleft, Int_t &pmtright){

  if(paddle==0){
    pmtleft=0;
    pmtright=1;
  }

  if(paddle==1){
    pmtleft=2;
    pmtright=3;
  }

  if(paddle==2){
    pmtleft=4;
    pmtright=5;
  }

  if(paddle==3){
    pmtleft=6;
    pmtright=7;
  }

  if(paddle==4){
    pmtleft=8;
    pmtright=9;
  }

  if(paddle==5){
    pmtleft=10;
    pmtright=11;
  }

  if(paddle==6){
    pmtleft=12;
    pmtright=13;
  }

  if(paddle==7){
    pmtleft=14;
    pmtright=15;
  }

  if(paddle==8){
    pmtleft=16;
    pmtright=17;
  }

  if(paddle==9){
    pmtleft=18;
    pmtright=19;
  }

  if(paddle==10){
    pmtleft=20;
    pmtright=21;
  }

  if(paddle==11){
    pmtleft=22;
    pmtright=23;
  }

  if(paddle==12){
    pmtleft=24;
    pmtright=25;
  }

  if(paddle==13){
    pmtleft=26;
    pmtright=27;
  }

  if(paddle==14){
    pmtleft=28;
    pmtright=29;
  }

  if(paddle==15){
    pmtleft=30;
    pmtright=31;
  }

  if(paddle==16){
    pmtleft=32;
    pmtright=33;
  }

  if(paddle==17){
    pmtleft=34;
    pmtright=35;
  }

  if(paddle==18){
    pmtleft=36;
    pmtright=37;
  }

  if(paddle==19){
    pmtleft=38;
    pmtright=39;
  }

  if(paddle==20){
    pmtleft=40;
    pmtright=41;
  }

  if(paddle==21){
    pmtleft=42;
    pmtright=43;
  }

  if(paddle==22){
    pmtleft=44;
    pmtright=45;
  }

  if(paddle==23){
    pmtleft=46;
    pmtright=47;
  }
  
  return;
}

//



// // gf Apr 07

void ToFLevel2::GetPaddleGeometry(Int_t plane, Int_t paddle, Float_t &xleft, Float_t &xright, Float_t &yleft, Float_t &yright){
  
  Int_t i1;

  Float_t tof11_x[8] = {-17.85,-12.75,-7.65,-2.55,2.55,7.65,12.75,17.85};
  Float_t tof12_y[6] = { -13.75,-8.25,-2.75,2.75,8.25,13.75};
  Float_t tof21_y[2] = { 3.75,-3.75};
  Float_t tof22_x[2] = { -4.5,4.5};
  Float_t tof31_x[3] = { -6.0,0.,6.0};
  Float_t tof32_y[3] = { -5.0,0.0,5.0};
	
  //  S11 8 paddles  33.0 x 5.1 cm
  //  S12 6 paddles  40.8 x 5.5 cm
  //  S21 2 paddles  18.0 x 7.5 cm
  //  S22 2 paddles  15.0 x 9.0 cm
  //  S31 3 paddles  15.0 x 6.0 cm
  //  S32 3 paddles  18.0 x 5.0 cm

  if(plane==0)
    {
      for (i1=0; i1<8;i1++){
	if(i1 == paddle){
	  xleft = tof11_x[i1] - 5.1/2.;
	  xright = tof11_x[i1] + 5.1/2.;
	  yleft = -33.0/2.;
	  yright = 33.0/2.;
	}
      }
    }
  
  if(plane==1)
    {
      for (i1=0; i1<6;i1++){
	if(i1 == paddle){
	  xleft = -40.8/2.;
	  xright = 40.8/2.;
	  yleft = tof12_y[i1] - 5.5/2.;
	  yright = tof12_y[i1] + 5.5/2.;
	}
      }
    }

  if(plane==2)
    {
      for (i1=0; i1<2;i1++){
	if(i1 == paddle){
	  xleft =  -18./2.;
	  xright = 18./2.;
	  yleft = tof21_y[i1] - 7.5/2.;
	  yright = tof21_y[i1] + 7.5/2.;
	}
      }
    }
  
  if(plane==3)
    {
      for (i1=0; i1<2;i1++){
	if(i1 == paddle){
	  xleft = tof22_x[i1] - 9.0/2.;
	  xright = tof22_x[i1] + 9.0/2.;
	  yleft = -15./2.;
	  yright = 15./2.;
	}
      }
    }


  if(plane==4)
    {
      for (i1=0; i1<3;i1++){
	if(i1 == paddle){
	  xleft = tof31_x[i1] - 6.0/2.;
	  xright = tof31_x[i1] + 6.0/2.;
	  yleft = -15./2.;
	  yright = 15./2.;
	}
      }
    }

  if(plane==5)
    {
      for (i1=0; i1<3;i1++){
	if(i1 == paddle){
	  xleft = -18.0/2.;
	  xright = 18.0/2.;
	  yleft = tof32_y[i1] - 5.0/2.;
	  yright = tof32_y[i1] + 5.0/2.;
	}
      }
    }
  return;
}

// gf Apr 07
/**
 * Method to get the paddle index (0,...23) if the plane ID and the paddle id in the plane is given. 
 * This method is the
 * "reverse" of method "GetPaddlePlane"
 * @param plane    (0 - 5)
 * @param paddle   (plane=0, paddle = 0,...5)
 * @param padid    (0 - 23)
 */
Int_t ToFLevel2::GetPaddleid(Int_t plane, Int_t paddle)
{

  Int_t padid=-1;
  Int_t pads11=8;
  Int_t pads12=6;
  Int_t pads21=2;
  Int_t pads22=2;
  Int_t pads31=3;
  //  Int_t pads32=3;


  if(plane == 0){
    padid=paddle;
  }

  if(plane == 1){
    padid=pads11+paddle;
  }

  if(plane == 2){
    padid=pads11+pads12+paddle;
  }

  if(plane == 3){
    padid=pads11+pads12+pads21+paddle;
  }

  if(plane == 4){
    padid=pads11+pads12+pads21+pads22+paddle;
  }

  if(plane == 5){
    padid=pads11+pads12+pads21+pads22+pads31+paddle;
  }

  return padid;

}


// gf Apr 07
/**
 * Method to get the plane ID and the paddle id in the plane if the paddle index (0,...23) is given. 
 * This method is the
 * "reverse" of method "GetPaddleid"
 * @param pad      (0 - 23)
 * @param plane    (0 - 5)
 * @param paddle   (plane=0, paddle = 0,...5)
 */
void ToFLevel2::GetPaddlePlane(Int_t pad, Int_t &plane, Int_t &paddle)
{

  Int_t pads11=8;
  Int_t pads12=6;
  Int_t pads21=2;
  Int_t pads22=2;
  Int_t pads31=3;
  // Int_t pads32=3;

  if(pad<8){
    plane=0;
    paddle=pad;
    return;
  }

  if(7<pad<14){
    plane=1;
    paddle=pad-pads11;
    return;
  }
  
  if(13<pad<16){
    plane=2;
    paddle=pad-pads11-pads12;
    return;
  }

  if(15<pad<18){
    plane=3;
    paddle=pad-pads11-pads12-pads21;
    return;
  }

  if(17<pad<21){
    plane=4;
    paddle=pad-pads11-pads12-pads21-pads22;
    return;
  }

  if(20<pad<24){
    plane=5;
    paddle=pad-pads11-pads12-pads21-pads22-pads31;
    return;
  }   

}


Int_t ToFLevel2::GetNPaddle(Int_t plane){

  Int_t npaddle=-1;

  Int_t pads11=8;
  Int_t pads12=6;
  Int_t pads21=2;
  Int_t pads22=2;
  Int_t pads31=3;
  Int_t pads32=3;

  if(plane==0)npaddle=pads11;
  if(plane==1)npaddle=pads12;
  if(plane==2)npaddle=pads21;
  if(plane==3)npaddle=pads22;
  if(plane==4)npaddle=pads31;
  if(plane==5)npaddle=pads32;

  return npaddle;

}

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



/**
 * Fills a struct cToFLevel2 with values from a ToFLevel2 object (to put data into a F77 common).
 */
void ToFLevel2::GetLevel2Struct(cToFLevel2 *l2) const{

  for(Int_t i=0;i<6;i++)
    l2->tof_j_flag[i]=tof_j_flag[i];

  if(ToFTrk){ //ELENA
      l2->ntoftrk = ToFTrk->GetEntries();
      for(Int_t j=0;j<l2->ntoftrk;j++){
	  l2->toftrkseqno[j]= ((ToFTrkVar*)ToFTrk->At(j))->trkseqno;
	  l2->npmttdc[j]= ((ToFTrkVar*)ToFTrk->At(j))->npmttdc;
	  for(Int_t i=0;i<l2->npmttdc[j];i++){
	      l2->pmttdc[i][j] = ((ToFTrkVar*)ToFTrk->At(j))->pmttdc.At(i);
	      l2->tdcflag[i][j] = ((ToFTrkVar*)ToFTrk->At(j))->tdcflag.At(i); // gf: 30 Nov 2006
	  }
	  for(Int_t i=0;i<13;i++)
	      l2->beta[i][j] = ((ToFTrkVar*)ToFTrk->At(j))->beta[i];
	  
	  l2->npmtadc[j]= ((ToFTrkVar*)ToFTrk->At(j))->npmtadc;
	  for(Int_t i=0;i<l2->npmtadc[j];i++){
	      l2->pmtadc[i][j] = ((ToFTrkVar*)ToFTrk->At(j))->pmtadc.At(i);
	      l2->adcflag[i][j] = ((ToFTrkVar*)ToFTrk->At(j))->adcflag.At(i); // gf: 30 Nov 2006
	      l2->dedx[i][j] = ((ToFTrkVar*)ToFTrk->At(j))->dedx.At(i);
	  }
	  for(Int_t i=0;i<3;i++){
	      l2->xtofpos[i][j]=((ToFTrkVar*)ToFTrk->At(j))->xtofpos[i];
	      l2->ytofpos[i][j]=((ToFTrkVar*)ToFTrk->At(j))->ytofpos[i];
	  }
	  for(Int_t i=0;i<6;i++){
	      l2->xtr_tof[i][j]=((ToFTrkVar*)ToFTrk->At(j))->xtr_tof[i];
	      l2->ytr_tof[i][j]=((ToFTrkVar*)ToFTrk->At(j))->ytr_tof[i];
	  }
      }
  } //ELENA
    
  if(PMT){ //ELENA
      l2->npmt = PMT->GetEntries();
      for(Int_t j=0;j<l2->npmt;j++){
	  l2->pmt_id[j] = ((ToFPMT*)PMT->At(j))->pmt_id;
	  l2->adc[j] =((ToFPMT*)PMT->At(j))->adc;
	  l2->tdc_tw[j] =((ToFPMT*)PMT->At(j))->tdc_tw;
      }
  } //ELENA
}
