/**
 * \file CaloAxis.h
 * \author Elena Vannuccini
 */
#if !defined(__CINT__) || defined(__MAKECINT__)

#include <TString.h>
#include <TH1F.h>
#include <TH2F.h>
#include <TMath.h>
#include <TLine.h>
#include <TPolyMarker.h>
#include <TSelector.h>
#include <TFile.h>

#include <stdlib.h>
#include <iostream>
using namespace std;

#include <PamLevel2.h>

#endif
//===============================================================================
//
//
//
//
//===============================================================================
/**
 * \brief Class to store the calorimeter hit pattern on the x or y view
 */
class CaloEvent : public TObject{

public:
//  calo event    
    vector<int> ids;  //strip 0-95
    vector<int> idp;  //plane 0-21
    vector<float> q; // signal
    vector<float> zcoord;  
    vector<float> xycoord; 

    
    void Add(int iis, int iip, float fq, float fz, float fxy);
    int  GetN(){ return (int)(q.size()); };

    void Reset();
    void Delete(){ Reset(); };

    ~CaloEvent(){ Delete(); };

    CaloEvent(){ Reset(); };
    CaloEvent( CaloLevel1* calo, int view, Bool_t usemechanicalalignement){ Set(calo,view,usemechanicalalignement); };
    CaloEvent( CaloLevel1* calo, int view){ Set(calo,view); };

    void Set(CaloLevel1* calo, int view, Bool_t usemechanicalalignement);
    void Set(CaloLevel1* calo, int view){ Set(calo,view,0); };

    ClassDef(CaloEvent,1);

};
//===============================================================================
//
//
//
//
//===============================================================================
/**
 * \brief Class to fit an axis through a calorimeter event. 
 *
 * The fit consists in an iterative procedure, where some hits are iterativelly 
 * excluded according to a given tolerance. Two methods are implemented to get the axis:
 * CaloAxis::FitAxis(...)   -- optimized for non-interacting particles
 * CaloAxis::FitShower(...) -- optimized for interacting particles
 *  
 */
class CaloAxis : public TObject {

public:

    CaloEvent *cevent;

//  fitted points
    vector<float> x;///< independent coordinates (z)
    vector<float> y;///< dependente coordinate (x/y)
    vector<float> w;///< fit weight
    vector<float> q;///< signal

    Float_t par[2];///< axis parameters: y = par[0] + x*par[1]
    Float_t covpar[2][2];///< parameter covariance matrix

    TPolyMarker *sel;
    TLine       *axis;
    
    float cog[22]; ///< baricenter (hits associated to the axis only)
    float qpl[22]; ///< total charge in each plane (hits associated to the axis only)
    
    void Init();

    void Set(CaloLevel1* calo, Int_t view){ cevent->Set(calo,view,0); };
    void Set(CaloLevel1* calo, Int_t view, Bool_t usemechanicalalignement){ cevent->Set(calo,view,usemechanicalalignement); };

    CaloAxis(){ cevent = new CaloEvent(); Init(); };
    CaloAxis(CaloLevel1* calo, Int_t view){ cevent = new CaloEvent(); Init(); Set(calo,view); };
    CaloAxis(CaloLevel1* calo, Int_t view, Bool_t usemechanicalalignement){ cevent = new CaloEvent(); Init(); Set(calo,view,usemechanicalalignement); };
    
    void Reset();

    void Delete(){ Reset(); delete cevent; };
    ~CaloAxis(){ Delete(); };

    void Add(float xin, float yin);
    void Add(float xin, float yin, float qin);
    void Add(float xin, float yin, float qin, float win);

    int Fit();

    void Print();

    float GetPar(Int_t i){return par[i];};
    int   GetN(){return (int)(x.size());};
    float* GetX();
    float* GetY();
    float* GetQ();
    float GetChi2();
    float GetQaxis();           ///< signal along the axis
    float GetQaxis(float toll); ///< signal along the axis
    float GetCOG(Int_t ip){ if(ip>=0 && ip<22)return cog[ip]; else return 0;}; ///< COG vs plane
    float GetQ(Int_t ip)  { if(ip>=0 && ip<22)return qpl[ip]; else return 0;}; ///< signal vs plane
    float GetQstrip();          ///< average signal per strip
    float GetYfit(float x){ return par[0]+x*par[1]; }; ///< extrapolated axis coordinate

    float GetXmin();
    float GetXmax();

    void Draw(int col);
    void Draw(){ Draw(5); };

    int FitAxis( CaloLevel1* calo , Int_t view , Float_t toll , Bool_t usemechanicalalignement );    
    int FitAxis( CaloLevel1* calo , Int_t view , Float_t toll ){ return FitAxis(calo,view,toll,0); };

    int FitShower( CaloLevel1* calo , Int_t view , Float_t toll , Bool_t usemechanicalalignement );    
    int FitShower( CaloLevel1* calo , Int_t view , Float_t toll ){ return FitShower(calo,view,toll,0); };

    ClassDef(CaloAxis,1);


};


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