#ifndef MARS_MAlphaFitter
#define MARS_MAlphaFitter

#ifndef MARS_MParContainer
#include "MParContainer.h"
#endif

#ifndef ROOT_TArrayD
#include <TArrayD.h>
#endif

#ifndef ROOT_TF1
#include <TF1.h>
#endif

class TH1D;

class MAlphaFitter : public MParContainer
{
private:
    Float_t fSigInt;
    Float_t fSigMax;
    Float_t fBgMin;
    Float_t fBgMax;
    Int_t   fPolynomOrder;

    Double_t fSignificance;
    Double_t fEventsExcess;
    Double_t fEventsSignal;
    Double_t fEventsBackground;

    Double_t fChiSqSignal;
    Double_t fChiSqBg;
    Double_t fIntegralMax;

    TArrayD fCoefficients;

    TF1 *fFunc;

public:
    // Implementing the function yourself is only about 5% faster
    MAlphaFitter(const char *name=0, const char *title=0) : fSigInt(15), fSigMax(75), fBgMin(45), fBgMax(85), fPolynomOrder(2), fCoefficients(3+fPolynomOrder+1), fFunc(new TF1("", Form("gaus(0) + pol%d(3)", fPolynomOrder), 0, 90))
    {
        fName  = name  ? name  : "MAlphaFitter";
        fTitle = title ? title : "Fit alpha";

        gROOT->GetListOfFunctions()->Remove(fFunc);
        fFunc->SetName("Dummy");
    }

    MAlphaFitter(const MAlphaFitter &f) : fFunc(0)
    {
        f.Copy(*this);
    }
    ~MAlphaFitter()
    {
        delete fFunc;
    }

    void Print(Option_t *o=0) const;
    void Copy(TObject &o) const;
    /*
    TObject *Clone(const char *name) const
    {
        return new MAlphaFitter(*this);
    }
    */

    void SetSignalIntegralMax(Float_t s)   { fSigInt       = s; }
    void SetSignalFitMax(Float_t s)        { fSigMax       = s; }
    void SetBackgroundFitMin(Float_t s)    { fBgMin        = s; }
    void SetBackgroundFitMax(Float_t s)    { fBgMax        = s; }
    void SetPolynomOrder(Int_t s)          { fPolynomOrder = s; delete fFunc; fFunc=new TF1 ("", Form("gaus(0) + pol%d(3)", s));
        gROOT->GetListOfFunctions()->Remove(fFunc);
        fFunc->SetName("Dummy");
        fCoefficients.Set(3+s+1); fCoefficients.Reset(); }

    Double_t GetEventsExcess() const       { return fEventsExcess; }
    Double_t GetEventsSignal() const       { return fEventsSignal; }
    Double_t GetEventsBackground() const   { return fEventsBackground; }

    Double_t GetSignificance() const       { return fSignificance; }
    Double_t GetChiSqSignal() const        { return fChiSqSignal; }
    Double_t GetChiSqBg() const            { return fChiSqBg; }

    Double_t GetGausSigma() const          { return fCoefficients[2]; }
    Double_t GetGausMu() const             { return fCoefficients[1]; }
    Double_t GetGausA() const              { return fCoefficients[0]; }
    Double_t GetCoefficient(Int_t i) const { return fCoefficients[i]; }
    const TArrayD &GetCoefficients() const { return fCoefficients; }

    void PaintResult(Float_t x=0.04, Float_t y=0.94, Float_t size=0.035) const;

    Bool_t Fit(TH1D &h, Bool_t paint=kFALSE);

    ClassDef(MAlphaFitter, 1)
};

#endif
