/**
 * \file CaloBragg.h
 * \author Emiliano Mocchiutti & Valeria Malvezzi & Daniele Tavagnacco
 */
#ifndef calobragg_h
#define calobragg_h
#define SQ(a) ( a * a )
#include <PamLevel2.h>

#include <TTree.h>
#include <TFriendElement.h>
#include <TChain.h>
#include <TFile.h>
#include <TList.h>
#include <TKey.h>
#include <TSystemFile.h>
#include <TStyle.h>
#include <TSystemDirectory.h>
#include <TSQLServer.h>
#include <TCanvas.h>
#include <TH2F.h>
#include <iostream>

using namespace std;


/**
 *
 * Class to store and calculate variables useful for nuclei analysis
 */
class CaloBragg : public TObject {

 private:
    //
    PamLevel2 *L2;
    Bool_t debug;
    Bool_t usetrack;
    Bool_t startZero;

    //
    // needed to avoid reprocessing the same event over and over to obtain the variables
    //
    UInt_t OBT;
    UInt_t PKT;
    UInt_t atime;
    Int_t tr;
    Int_t sntr;
    //parametri calorimetro
    Int_t NPLA;
    Int_t NCHA;
    Int_t nView;
    
    Float_t AA;//mm larghezza strip
    Float_t ADIST;//mm distanza tra pad
    Float_t PIANO;//mm distanza 
    
    Float_t ySi;//mm spessore silicio
    Float_t yW;//mm spessore tungsteno
    Float_t rhoSi;//g/cm3 densita' silicio
    Float_t rhoW;//g/cm3 densita' tugsteno
    Float_t MIP;//Mev g/cm2 energia al minimo nel silicio per 0.38 mm
    
    Float_t emin;
    Float_t fzeta;
    Float_t fene;
	Int_t 	fiso;
    //
    Bool_t usepl18x;
    Bool_t newchi2;
    Bool_t usenewBB;
    Int_t ndf;


    //parametri bethe-bloch
    Float_t pigr;
    Float_t Na;
    Float_t ZA; /*Z/A per Si*/
    Float_t ISi; /*MeV*/
    Float_t IW; /*MeV*/
    Float_t Me; /* MeV*/
    Float_t MassP;/*MeV*/
    Float_t r2; /*ro*ro in cm */
    
    //variabili globali caricabili
    Float_t Integrale;
    Float_t bestchi2[5];
/*     Float_t qtchi2; */
/*     Float_t qtz; */
/*     Float_t qtetot; */
/*     Float_t qtpskip; */
    Float_t lpchi2;
    Float_t lpz;
    Float_t lpisotope;
    Float_t lpetot;
    Float_t lppskip;
    Float_t calorimetro[44][2];
    Float_t spessore[4];
    Float_t estremi[2][2];//[0][0]primo piano [0][1]energia primo
                        //[1][0]ultim piano [1][1]energia ultim
    //Float_t shift[2][22];//shift dei piani
    //Float_t piano[22]; //posizione z dei piani
    Float_t elem[32][7];//A degli elementi compresi isotopi
    //

    Float_t dEplan[2*22];//energia rilasciata calcolata

/*     void SWAP(Float_t*,Float_t*); */
    void LoadParam();
    void conversione();
    void BetheBloch(Float_t *,Float_t *,Float_t *,Float_t *,Float_t *,Float_t *, Float_t);
    void ELOSS(Float_t *,Int_t *,Int_t *, Float_t *, Float_t *, Float_t);
    void Enetrack(Int_t *,Int_t *, Float_t *, Float_t *,Float_t *,Float_t * );
    void chiquadro(Float_t *, Float_t *);
    void loopze(Float_t ,Float_t ,Float_t ,Float_t, Int_t  );
    void mediatroncata();
    void Zdaloop();
    void CleanPlanes(Float_t epiano[22][2], Bool_t zpiano[22][2]);

 public:
    //
    void SetStartZero(Bool_t yes=false){ startZero = yes;};
    //
    Float_t Get_firstplane(){ Process(); return estremi[0][0];}; ///< Number of available dE/dx measurements before interaction or exit from the calo (interaction plane) 
    Float_t Get_lastplane(){ Process(); return estremi[1][0];}; ///< Number of available dE/dx measurements before interaction or exit from the calo (interaction plane) 
/*     Float_t Get_qtchi2(){ Process(); return qtchi2;}; ///< Number of available dE/dx measurements before interaction or exit from the calo (interaction plane)  */
/*     Float_t Get_qtz(){ Process(); return qtz;}; ///< Number of available dE/dx measurements before interaction or exit from the calo (interaction plane)  */
/*     Float_t Get_qtetot(){ Process(); return qtetot;}; ///< Number of available dE/dx measurements before interaction or exit from the calo (interaction plane)  */
/*     Float_t Get_qtpskip(){ Process(); return qtpskip;}; ///< Number of available dE/dx measurements before interaction or exit from the calo (interaction plane)  */
    Float_t Get_lpchi2(){ Process(); return lpchi2;}; ///< Number of available dE/dx measurements before interaction or exit from the calo (interaction plane) 
    Float_t Get_lpz(){ Process(); return lpz;}; ///< Number of available dE/dx measurements before interaction or exit from the calo (interaction plane) 
    Float_t Get_mass(){ Process(); return elem[(Int_t)lpz - 1][(Int_t)lpisotope];}; ///< Number of available dE/dx measurements before interaction or exit from the calo (interaction plane) 
    Float_t Get_lpetot(){ Process(); return lpetot;}; ///< Number of available dE/dx measurements before interaction or exit from the calo (interaction plane) 
    Float_t Get_lppskip(){ Process(); return lppskip;}; ///< Number of available dE/dx measurements before interaction or exit from the calo (interaction plane) 

	Float_t Integral();
	Float_t LastIntegral();

    void ForceZeta(Float_t zeta){ fzeta = zeta;};
    void ForceEne(Float_t ener ){ fene = ener;};
    void ForceIso(Int_t isor ){ fiso = isor;};
    void ForceProcessing(){ sntr = -1000.;};

    void UsePlane18X(Bool_t use){usepl18x = use;};

    void UseNewChi2(Bool_t use){newchi2 = use;};
    void UseNewBB(Bool_t use){usenewBB = use;};
    //

    //
    CaloBragg();
    CaloBragg(PamLevel2 *L2);
    ~CaloBragg(){ Delete(); };
    //
    void Draw();
    void Draw(Int_t,Int_t, Float_t);
    void SetDebug(Bool_t d){ debug=d; };
    void UseTrack(Bool_t d){ usetrack=d; };
    //
    void Clear();
    void Clear(Option_t *option){Clear();};
    void Delete();
    void Delete(Option_t *option){Delete();};
    //
    void Process(); ///< Process data for track number 0
    void Process(Int_t ntr); ///< Process data for track number ntr
    void Print();
    void Print(Option_t *option){Print();};
    //
    ClassDef(CaloBragg,6);
};

#endif

