// Author: Kerstin Tackmann, Andreas Hoecker, Heiko Lacker

/**********************************************************************************
 *                                                                                *
 * Project: TSVDUnfold - data unfolding based on Singular Value Decomposition     *
 * Package: ROOT                                                                  *
 * Class  : TSVDUnfold                                                            *
 *                                                                                *
 * Description:                                                                   *
 *      Single class implementation of SVD data unfolding based on:               *
 *          A. Hoecker, V. Kartvelishvili,                                        *
 *          "SVD approach to data unfolding"                                      *
 *          NIM A372, 469 (1996) [hep-ph/9509307]                                 *
 *                                                                                *
 * Authors:                                                                       *
 *      Kerstin Tackmann <Kerstin.Tackmann@cern.ch>   - CERN, Switzerland         *
 *      Andreas Hoecker  <Andreas.Hoecker@cern.ch>    - CERN, Switzerland         *
 *      Heiko Lacker     <lacker@physik.hu-berlin.de> - Humboldt U, Germany       *
 *                                                                                *
 * Copyright (c) 2010:                                                            *
 *      CERN, Switzerland                                                         *
 *      Humboldt University, Germany                                              *
 *                                                                                *
 **********************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TSVDUnfold                                                           //
//                                                                      //
// Data unfolding using Singular Value Decomposition (hep-ph/9509307)   //
// Authors: Kerstin Tackmann, Andreas Hoecker, Heiko Lacker             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef TSVDUNFOLD_H
#define TSVDUNFOLD_H

#ifndef ROOT_TObject
#include "TObject.h"
#endif
#ifndef ROOT_TMatrixD
#include "TMatrixD.h"
#endif
#ifndef ROOT_TVectorD
#include "TVectorD.h"
#endif
#ifndef ROOT_TMatrixDSym
#include "TMatrixDSym.h"
#endif

class TH1D;
class TH2D;

class TSVDUnfold : public TObject {

public:

   // Constructor
   // Initialisation of unfolding
   // "bdat" - measured data distribution (number of events)
   // "Bcov" - covariance matrix for measured data distribution
   // "bini" - reconstructed MC distribution (number of events)
   // "xini" - truth MC distribution (number of events)
   // "Adet" - detector response matrix (number of events)
   TSVDUnfold( const TH1D* bdat, const TH1D* bini, const TH1D* xini, const TH2D* Adet );
   TSVDUnfold( const TH1D* bdat, TH2D* Bcov, const TH1D* bini, const TH1D* xini, const TH2D* Adet );
   TSVDUnfold( const TSVDUnfold& other );

   // Destructor
   virtual ~TSVDUnfold();

   // Set option to normalize unfolded spectrum to unit area
   // "normalize" - switch
   void     SetNormalize ( Bool_t normalize ) { fNormalize = normalize; }

   // Do the unfolding
   // "kreg"   - number of singular values used (regularisation)
   TH1D*    Unfold       ( Int_t kreg );

   // Determine for given input error matrix covariance matrix of unfolded
   // spectrum from toy simulation
   // "cov"    - covariance matrix on the measured spectrum, to be propagated
   // "ntoys"  - number of pseudo experiments used for the propagation
   // "seed"   - seed for pseudo experiments
   TH2D*    GetUnfoldCovMatrix( const TH2D* cov, Int_t ntoys, Int_t seed = 1 );

   // Determine covariance matrix of unfolded spectrum from finite statistics in
   // response matrix
   // "ntoys"  - number of pseudo experiments used for the propagation
   // "seed"   - seed for pseudo experiments
   TH2D*    GetAdetCovMatrix( Int_t ntoys, Int_t seed=1 );

   // Regularisation parameter
   Int_t    GetKReg() const { return fKReg; }

   // Obtain the distribution of |d| (for determining the regularization)
   TH1D*    GetD() const;

   // Obtain the distribution of singular values
   TH1D*    GetSV() const;

   // Obtain the computed regularized covariance matrix
   TH2D*    GetXtau() const;

   // Obtain the computed inverse of the covariance matrix
   TH2D*    GetXinv() const;

   //Obtain the covariance matrix on the data
   TH2D*    GetBCov() const;

   // Helper functions
   Double_t ComputeChiSquared( const TH1D& truspec, const TH1D& unfspec );

private:

   // Helper functions for vector and matrix operations
   void            FillCurvatureMatrix( TMatrixD& tCurv, TMatrixD& tC ) const;
   static Double_t GetCurvature       ( const TVectorD& vec, const TMatrixD& curv );

   void            InitHistos  ( );

   // Helper functions
   static void     H2V      ( const TH1D* histo, TVectorD& vec   );
   static void     H2Verr   ( const TH1D* histo, TVectorD& vec   );
   static void     V2H      ( const TVectorD& vec, TH1D& histo   );
   static void     H2M      ( const TH2D* histo, TMatrixD& mat   );
   static void     M2H      ( const TMatrixD& mat, TH2D& histo   );
   static TMatrixD MatDivVec( const TMatrixD& mat, const TVectorD& vec, Int_t zero=0 );
   static TVectorD CompProd ( const TVectorD& vec1, const TVectorD& vec2 );

   static TVectorD VecDiv                 ( const TVectorD& vec1, const TVectorD& vec2, Int_t zero = 0 );
   static void     RegularisedSymMatInvert( TMatrixDSym& mat, Double_t eps = 1e-3 );

   // Class members
   Int_t       fNdim;        //! Truth and reconstructed dimensions
   Int_t       fDdim;        //! Derivative for curvature matrix
   Bool_t      fNormalize;   //! Normalize unfolded spectrum to 1
   Int_t       fKReg;        //! Regularisation parameter
   TH1D*       fDHist;       //! Distribution of d (for checking regularization)
   TH1D*       fSVHist;      //! Distribution of singular values
   TH2D*       fXtau;        //! Computed regularized covariance matrix
   TH2D*       fXinv;        //! Computed inverse of covariance matrix

   // Input histos
   const TH1D* fBdat;        // measured distribution (data)
   TH2D* fBcov;        // covariance matrix of measured distribution (data)
   const TH1D* fBini;        // reconstructed distribution (MC)
   const TH1D* fXini;        // truth distribution (MC)
   const TH2D* fAdet;        // Detector response matrix

   // Evaluation of covariance matrices
   TH1D*       fToyhisto;    //! Toy MC histogram
   TH2D*       fToymat;      //! Toy MC detector response matrix
   Bool_t      fToyMode;     //! Internal switch for covariance matrix propagation
   Bool_t      fMatToyMode;  //! Internal switch for evaluation of statistical uncertainties from response matrix


   ClassDef( TSVDUnfold, 0 ) // Data unfolding using Singular Value Decomposition (hep-ph/9509307)
};

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