#ifndef ALIUNFOLDING_H
#define ALIUNFOLDING_H
#include "TObject.h"
#include <TMatrixD.h>
#include <TVectorD.h>
class TH1;
class TH2;
class TF1;
class TCanvas;
class TVirtualPad;
class TAxis;
class AliUnfolding : public TObject
{
public:
enum RegularizationType { kNone = 0, kPol0, kPol1, kLog, kEntropy, kCurvature, kRatio, kPowerLaw, kLogLog };
enum MethodType { kInvalid = -1, kChi2Minimization = 0, kBayesian = 1, kFunction = 2};
virtual ~AliUnfolding() {};
static void SetUnfoldingMethod(MethodType methodType);
static void SetCreateOverflowBin(Float_t overflowBinLimit);
static void SetSkipBinsBegin(Int_t nBins);
static void SetNbins(Int_t nMeasured, Int_t nUnfolded);
static void SetChi2Regularization(RegularizationType type, Float_t weight);
static void SetMinuitStepSize(Float_t stepSize) { fgMinuitStepSize = stepSize; }
static void SetMinuitPrecision(Float_t pres) {fgMinuitPrecision = pres;}
static void SetMinuitMaxIterations(Int_t iter) {fgMinuitMaxIterations = iter;}
static void SetMinuitStrategy(Double_t strat) {fgMinuitStrategy = strat;}
static void SetMinimumInitialValue(Bool_t flag, Float_t value = -1) { fgMinimumInitialValue = flag; fgMinimumInitialValueFix = value; }
static void SetNormalizeInput(Bool_t flag) { fgNormalizeInput = flag; }
static void SetNotFoundEvents(Float_t notFoundEvents) { fgNotFoundEvents = notFoundEvents; }
static void SetSkip0BinInChi2(Bool_t flag) { fgSkipBin0InChi2 = flag; }
static void SetBayesianParameters(Float_t smoothing, Int_t nIterations);
static void SetFunction(TF1* function);
static void SetDebug(Bool_t flag) { fgDebug = flag; }
static void SetPowern(Int_t n) {fgPowern = -1*n;}
static Int_t Unfold(TH2* correlation, TH1* efficiency, TH1* measured, TH1* initialConditions, TH1* result, Bool_t check = kFALSE);
static Int_t UnfoldGetBias(TH2* correlation, TH1* efficiency, TH1* measured, TH1* initialConditions, TH1* result);
static TH1* GetPenaltyPlot(Double_t* params);
static TH1* GetPenaltyPlot(TH1* corrected);
static TH1* GetResidualsPlot(Double_t* params);
static TH1* GetResidualsPlot(TH1* corrected);
static Double_t GetChi2FromFit() {return fChi2FromFit;}
static Double_t GetPenaltyVal() {return fPenaltyVal;}
static Double_t GetAvgResidual() {return fAvgResidual;}
static void DrawResults(TH2* correlation, TH1* efficiency, TH1* measured, TH1* initialConditions, TCanvas *canvas = 0, Int_t reuseHists = kFALSE,TH1 *unfolded=0);
static void InteractiveUnfold(TH2* correlation, TH1* efficiency, TH1* measured, TH1* initialConditions);
static void RedrawInteractive();
protected:
AliUnfolding() {};
static Int_t UnfoldWithMinuit(TH2* correlation, TH1* efficiency, TH1* measured, TH1* initialConditions, TH1* result, Bool_t check);
static Int_t UnfoldWithBayesian(TH2* correlation, TH1* aEfficiency, TH1* measured, TH1* initialConditions, TH1* aResult);
static Int_t UnfoldWithFunction(TH2* correlation, TH1* efficiency, TH1* measured, TH1* , TH1* aResult);
static void CreateOverflowBin(TH2* correlation, TH1* measured);
static void SetStaticVariables(TH2* correlation, TH1* measured, TH1* efficiency);
static void MakePads();
static void DrawGuess(Double_t *params, TVirtualPad *pfolded=0, TVirtualPad *pres=0, TVirtualPad *ppen=0, Int_t reuseHists = kFALSE, TH1* unfolded=0);
static Double_t RegularizationPol0(TVectorD& params);
static Double_t RegularizationPol1(TVectorD& params);
static Double_t RegularizationTotalCurvature(TVectorD& params);
static Double_t RegularizationEntropy(TVectorD& params);
static Double_t RegularizationLog(TVectorD& params);
static Double_t RegularizationRatio(TVectorD& params);
static Double_t RegularizationPowerLaw(TVectorD& params);
static Double_t RegularizationLogLog(TVectorD& params);
static void Chi2Function(Int_t&, Double_t*, Double_t& chi2, Double_t *params, Int_t);
static void TF1Function(Int_t& unused1, Double_t* unused2, Double_t& chi2, Double_t *params, Int_t unused3);
static TMatrixD* fgCorrelationMatrix;
static TMatrixD* fgCorrelationMatrixSquared;
static TMatrixD* fgCorrelationCovarianceMatrix;
static TVectorD* fgCurrentESDVector;
static TVectorD* fgEntropyAPriori;
static TVectorD* fgEfficiency;
static TAxis *fgUnfoldedAxis;
static TAxis *fgMeasuredAxis;
static TF1* fgFitFunction;
static MethodType fgMethodType;
static Int_t fgMaxParams;
static Int_t fgMaxInput;
static Float_t fgOverflowBinLimit;
static RegularizationType fgRegularizationType;
static Float_t fgRegularizationWeight;
static Int_t fgSkipBinsBegin;
static Float_t fgMinuitStepSize;
static Float_t fgMinuitPrecision;
static Int_t fgMinuitMaxIterations;
static Double_t fgMinuitStrategy;
static Bool_t fgMinimumInitialValue;
static Float_t fgMinimumInitialValueFix;
static Bool_t fgNormalizeInput;
static Float_t fgNotFoundEvents;
static Bool_t fgSkipBin0InChi2;
static Float_t fgBayesianSmoothing;
static Int_t fgBayesianIterations;
static Bool_t fgDebug;
static Int_t fgCallCount;
static Int_t fgPowern;
static Double_t fChi2FromFit;
static Double_t fPenaltyVal;
static Double_t fAvgResidual;
static Int_t fgPrintChi2Details;
static TCanvas *fgCanvas;
static TH1 *fghUnfolded;
static TH2 *fghCorrelation;
static TH1 *fghEfficiency;
static TH1 *fghMeasured;
private:
AliUnfolding(const AliUnfolding&);
AliUnfolding& operator=(const AliUnfolding&);
ClassDef(AliUnfolding, 0);
};
#endif