ROOT logo
/* $Id$ */

#ifndef ALIUNFOLDING_H
#define ALIUNFOLDING_H

//
// class that implements several unfolding methods
// I.e. chi2 minimization and bayesian unfolding
// The whole class is static and not thread-safe (due to the fact that MINUIT unfolding is not thread-safe)
//

// TMatrixD, TVectorD defined here, because it does not seem possible to predeclare these (or i do not know how)
// -->
// $ROOTSYS/include/TVectorDfwd.h:21: conflicting types for `typedef struct TVectorT<Double_t> TVectorD'
// PWG0/AliUnfolding.h:21: previous declaration as `struct TVectorD'

#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* /* initialConditions */, 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 variable to be accessed by MINUIT
    static TMatrixD* fgCorrelationMatrix;            // contains fCurrentCorrelation in matrix form
    static TMatrixD* fgCorrelationMatrixSquared;     // contains squared fCurrentCorrelation in matrix form
    static TMatrixD* fgCorrelationCovarianceMatrix;  // contains the errors of fCurrentESD
    static TVectorD* fgCurrentESDVector;             // contains fCurrentESD
    static TVectorD* fgEntropyAPriori;               // a-priori distribution for entropy regularization
    static TVectorD* fgEfficiency;                   // efficiency
    /*
    static TVectorD* fgBinWidths;                    // bin widths to be taken into account in regularization
    static TVectorD* fgBinPos;                       // bin positions of unfolded
    */
    static TAxis *fgUnfoldedAxis;                    // bin widths and positions for unfolded
    static TAxis *fgMeasuredAxis;                    // bin widths and positions for measured

    static TF1* fgFitFunction;                       // fit function

    // --- configuration params follow ---
    static MethodType fgMethodType;                  // unfolding method to be used
    static Int_t fgMaxParams;                        // bins in unfolded histogram = number of fit params
    static Int_t fgMaxInput;                         // bins in measured histogram
    static Float_t fgOverflowBinLimit;               // to fix fluctuations at high multiplicities, all entries above the limit are summarized in one bin

    static RegularizationType fgRegularizationType;  // regularization that is used during Chi2 method
    static Float_t fgRegularizationWeight;           // factor for regularization term
    static Int_t fgSkipBinsBegin;                    // (optional) skip the given number of bins in the regularization
    static Float_t fgMinuitStepSize;                 // (usually not needed to be changed) step size in minimization
    static Float_t fgMinuitPrecision;                // precision used by minuit. default = 1e-6
    static Int_t   fgMinuitMaxIterations;            // maximum number of iterations used by minuit. default = 5000
    static Double_t fgMinuitStrategy;                // minuit strategy: 0 (low), 1 (default), 2 (high)
    static Bool_t fgMinimumInitialValue;             // set all initial values at least to the smallest value among the initial values
    static Float_t fgMinimumInitialValueFix;         // use this as the minimum initial value instead of determining it automatically
    static Bool_t fgNormalizeInput;                  // normalize input spectrum
    static Float_t fgNotFoundEvents;                 // constraint on the total number of not found events sum(guess * (1/eff -1))
    static Bool_t fgSkipBin0InChi2;                  // skip bin 0 (= 0 measured) in chi2 function

    static Float_t fgBayesianSmoothing;              // smoothing parameter (0 = no smoothing)
    static Int_t   fgBayesianIterations;             // number of iterations in Bayesian method

    static Bool_t fgDebug;                           // debug flag
    // --- end of configuration ---
    
    static Int_t fgCallCount;                        // call count to chi2 function

    static Int_t fgPowern;                           // power of power law for regularization with power law

    static Double_t fChi2FromFit;                    // Chi2 from fit at current iteration
    static Double_t fPenaltyVal;                     // Penalty value at current iteration (\beta * PU)
    static Double_t fAvgResidual;                    // Sum residuals / nbins

    static Int_t fgPrintChi2Details;                 // debug for chi2 calc

    // Pointers for interactive unfolder
    static TCanvas *fgCanvas;                        // Canvas for interactive unfolder
    static TH1 *fghUnfolded;                         // Unfolding result for interactive unfolder
    static TH2 *fghCorrelation;                      // Response matrix for interactive unfolder
    static TH1 *fghEfficiency;                       // Efficiency histo for interactive unfolder
    static TH1 *fghMeasured;                         // Measured distribution for interactive unfolder

private:
    AliUnfolding(const AliUnfolding&);
    AliUnfolding& operator=(const AliUnfolding&);

  ClassDef(AliUnfolding, 0);
};

#endif

 AliUnfolding.h:1
 AliUnfolding.h:2
 AliUnfolding.h:3
 AliUnfolding.h:4
 AliUnfolding.h:5
 AliUnfolding.h:6
 AliUnfolding.h:7
 AliUnfolding.h:8
 AliUnfolding.h:9
 AliUnfolding.h:10
 AliUnfolding.h:11
 AliUnfolding.h:12
 AliUnfolding.h:13
 AliUnfolding.h:14
 AliUnfolding.h:15
 AliUnfolding.h:16
 AliUnfolding.h:17
 AliUnfolding.h:18
 AliUnfolding.h:19
 AliUnfolding.h:20
 AliUnfolding.h:21
 AliUnfolding.h:22
 AliUnfolding.h:23
 AliUnfolding.h:24
 AliUnfolding.h:25
 AliUnfolding.h:26
 AliUnfolding.h:27
 AliUnfolding.h:28
 AliUnfolding.h:29
 AliUnfolding.h:30
 AliUnfolding.h:31
 AliUnfolding.h:32
 AliUnfolding.h:33
 AliUnfolding.h:34
 AliUnfolding.h:35
 AliUnfolding.h:36
 AliUnfolding.h:37
 AliUnfolding.h:38
 AliUnfolding.h:39
 AliUnfolding.h:40
 AliUnfolding.h:41
 AliUnfolding.h:42
 AliUnfolding.h:43
 AliUnfolding.h:44
 AliUnfolding.h:45
 AliUnfolding.h:46
 AliUnfolding.h:47
 AliUnfolding.h:48
 AliUnfolding.h:49
 AliUnfolding.h:50
 AliUnfolding.h:51
 AliUnfolding.h:52
 AliUnfolding.h:53
 AliUnfolding.h:54
 AliUnfolding.h:55
 AliUnfolding.h:56
 AliUnfolding.h:57
 AliUnfolding.h:58
 AliUnfolding.h:59
 AliUnfolding.h:60
 AliUnfolding.h:61
 AliUnfolding.h:62
 AliUnfolding.h:63
 AliUnfolding.h:64
 AliUnfolding.h:65
 AliUnfolding.h:66
 AliUnfolding.h:67
 AliUnfolding.h:68
 AliUnfolding.h:69
 AliUnfolding.h:70
 AliUnfolding.h:71
 AliUnfolding.h:72
 AliUnfolding.h:73
 AliUnfolding.h:74
 AliUnfolding.h:75
 AliUnfolding.h:76
 AliUnfolding.h:77
 AliUnfolding.h:78
 AliUnfolding.h:79
 AliUnfolding.h:80
 AliUnfolding.h:81
 AliUnfolding.h:82
 AliUnfolding.h:83
 AliUnfolding.h:84
 AliUnfolding.h:85
 AliUnfolding.h:86
 AliUnfolding.h:87
 AliUnfolding.h:88
 AliUnfolding.h:89
 AliUnfolding.h:90
 AliUnfolding.h:91
 AliUnfolding.h:92
 AliUnfolding.h:93
 AliUnfolding.h:94
 AliUnfolding.h:95
 AliUnfolding.h:96
 AliUnfolding.h:97
 AliUnfolding.h:98
 AliUnfolding.h:99
 AliUnfolding.h:100
 AliUnfolding.h:101
 AliUnfolding.h:102
 AliUnfolding.h:103
 AliUnfolding.h:104
 AliUnfolding.h:105
 AliUnfolding.h:106
 AliUnfolding.h:107
 AliUnfolding.h:108
 AliUnfolding.h:109
 AliUnfolding.h:110
 AliUnfolding.h:111
 AliUnfolding.h:112
 AliUnfolding.h:113
 AliUnfolding.h:114
 AliUnfolding.h:115
 AliUnfolding.h:116
 AliUnfolding.h:117
 AliUnfolding.h:118
 AliUnfolding.h:119
 AliUnfolding.h:120
 AliUnfolding.h:121
 AliUnfolding.h:122
 AliUnfolding.h:123
 AliUnfolding.h:124
 AliUnfolding.h:125
 AliUnfolding.h:126
 AliUnfolding.h:127
 AliUnfolding.h:128
 AliUnfolding.h:129
 AliUnfolding.h:130
 AliUnfolding.h:131
 AliUnfolding.h:132
 AliUnfolding.h:133
 AliUnfolding.h:134
 AliUnfolding.h:135
 AliUnfolding.h:136
 AliUnfolding.h:137
 AliUnfolding.h:138
 AliUnfolding.h:139
 AliUnfolding.h:140
 AliUnfolding.h:141
 AliUnfolding.h:142
 AliUnfolding.h:143
 AliUnfolding.h:144
 AliUnfolding.h:145
 AliUnfolding.h:146
 AliUnfolding.h:147
 AliUnfolding.h:148
 AliUnfolding.h:149
 AliUnfolding.h:150
 AliUnfolding.h:151
 AliUnfolding.h:152
 AliUnfolding.h:153
 AliUnfolding.h:154
 AliUnfolding.h:155
 AliUnfolding.h:156
 AliUnfolding.h:157
 AliUnfolding.h:158
 AliUnfolding.h:159
 AliUnfolding.h:160
 AliUnfolding.h:161
 AliUnfolding.h:162