ROOT logo

From $ROOTSYS/tutorials/math/TSVDUnfoldExample.C

//  Data unfolding using Singular Value Decomposition 
// 
//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TSVDUnfold example                                                   //
//                                                                      //
// Data unfolding using Singular Value Decomposition (hep-ph/9509307)   //
// Authors: Kerstin Tackmann, Andreas Hoecker, Heiko Lacker             //
//                                                                      //
// Example distribution and smearing model from Tim Adye (RAL)          //
//                                                                      //
// Nov 23, 2010                                                         //
//////////////////////////////////////////////////////////////////////////

#include <iostream>

#include "TROOT.h"
#include "TSystem.h"
#include "TStyle.h"
#include "TRandom3.h"
#include "TString.h"
#include "TMath.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TLegend.h"
#include "TCanvas.h"
#include "TColor.h"
#include "TLine.h"

#if not defined(__CINT__) || defined(__MAKECINT__)
#include "TSVDUnfold.h"
#endif

Double_t Reconstruct( Double_t xt, TRandom3& R )
{
   // apply some Gaussian smearing + bias and efficiency corrections to fake reconstruction
   const Double_t cutdummy = -99999.0;
   Double_t xeff = 0.3 + (1.0 - 0.3)/20.0*(xt + 10.0);  // efficiency
   Double_t x    = R.Rndm();
   if (x > xeff) return cutdummy;
   else {
     Double_t xsmear= R.Gaus(-2.5,0.2); // bias and smear
     return xt+xsmear;
   }
}

void TSVDUnfoldExample() 
{
   gROOT->Reset();
   gROOT->SetStyle("Plain");
   gStyle->SetOptStat(0);

   TRandom3 R;

   const Double_t cutdummy= -99999.0;
   
   // --- Data/MC toy generation -----------------------------------

   // The MC input
   Int_t nbins = 40;
   TH1D *xini = new TH1D("xini", "MC truth", nbins, -10.0, 10.0);
   TH1D *bini = new TH1D("bini", "MC reco", nbins, -10.0, 10.0);
   TH2D *Adet = new TH2D("Adet", "detector response", nbins, -10.0, 10.0, nbins, -10.0, 10.0);

   // Data
   TH1D *data = new TH1D("data", "data", nbins, -10.0, 10.0);
   // Data "truth" distribution to test the unfolding
   TH1D *datatrue = new TH1D("datatrue", "data truth", nbins, -10.0, 10.0);
   // Statistical covariance matrix
   TH2D *statcov = new TH2D("statcov", "covariance matrix", nbins, -10.0, 10.0, nbins, -10.0, 10.0);

   // Fill the MC using a Breit-Wigner, mean 0.3 and width 2.5.
   for (Int_t i= 0; i<100000; i++) {
      Double_t xt = R.BreitWigner(0.3, 2.5);
      xini->Fill(xt);
      Double_t x = Reconstruct( xt, R );
      if (x != cutdummy) {
         Adet->Fill(x, xt);
         bini->Fill(x);
      }
   }

   // Fill the "data" with a Gaussian, mean 0 and width 2.
   for (Int_t i=0; i<10000; i++) {
      Double_t xt = R.Gaus(0.0, 2.0);
      datatrue->Fill(xt);
      Double_t x = Reconstruct( xt, R );
      if (x != cutdummy) 
      data->Fill(x);
   }

   cout << "Created toy distributions and errors for: " << endl;
   cout << "... \"true MC\"   and \"reconstructed (smeared) MC\"" << endl;
   cout << "... \"true data\" and \"reconstructed (smeared) data\"" << endl;
   cout << "... the \"detector response matrix\"" << endl;

   // Fill the data covariance matrix
   for (int i=1; i<=data->GetNbinsX(); i++) {
       statcov->SetBinContent(i,i,data->GetBinError(i)*data->GetBinError(i)); 
   }

   // --- Here starts the actual unfolding -------------------------

   // Create TSVDUnfold object and initialise
   TSVDUnfold *tsvdunf = new TSVDUnfold( data, statcov, bini, xini, Adet );

   // It is possible to normalise unfolded spectrum to unit area
   tsvdunf->SetNormalize( kFALSE ); // no normalisation here

   // Perform the unfolding with regularisation parameter kreg = 13
   // - the larger kreg, the finer grained the unfolding, but the more fluctuations occur
   // - the smaller kreg, the stronger is the regularisation and the bias
   TH1D* unfres = tsvdunf->Unfold( 13 );

   // Get the distribution of the d to cross check the regularization
   // - choose kreg to be the point where |d_i| stop being statistically significantly >>1
   TH1D* ddist = tsvdunf->GetD();

   // Get the distribution of the singular values
   TH1D* svdist = tsvdunf->GetSV();

   // Compute the error matrix for the unfolded spectrum using toy MC
   // using the measured covariance matrix as input to generate the toys
   // 100 toys should usually be enough
   // The same method can be used for different covariance matrices separately.
   TH2D* ustatcov = tsvdunf->GetUnfoldCovMatrix( statcov, 100 );   

   // Now compute the error matrix on the unfolded distribution originating
   // from the finite detector matrix statistics
   TH2D* uadetcov = tsvdunf->GetAdetCovMatrix( 100 );   

   // Sum up the two (they are uncorrelated)
   ustatcov->Add( uadetcov );

   //Get the computed regularized covariance matrix (always corresponding to total uncertainty passed in constructor) and add uncertainties from finite MC statistics. 
   TH2D* utaucov = tsvdunf->GetXtau();
   utaucov->Add( uadetcov );

   //Get the computed inverse of the covariance matrix
   TH2D* uinvcov = tsvdunf->GetXinv();

   
   // --- Only plotting stuff below ------------------------------

   for (int i=1; i<=unfres->GetNbinsX(); i++) {
      unfres->SetBinError(i, TMath::Sqrt(utaucov->GetBinContent(i,i)));
   }

   // Renormalize just to be able to plot on the same scale
   xini->Scale(0.7*datatrue->Integral()/xini->Integral());

   TLegend *leg = new TLegend(0.58,0.68,0.99,0.88);
   leg->SetBorderSize(0);
   leg->SetFillColor(0);
   leg->SetFillStyle(0);
   leg->AddEntry(unfres,"Unfolded Data","p");
   leg->AddEntry(datatrue,"True Data","l");
   leg->AddEntry(data,"Reconstructed Data","l");
   leg->AddEntry(xini,"True MC","l");

   TCanvas *c1 = new TCanvas( "c1", "Unfolding toy example with TSVDUnfold", 900, 800 );

   // --- Style settings -----------------------------------------
   Int_t c_Canvas    = TColor::GetColor( "#f0f0f0" );
   Int_t c_FrameFill = TColor::GetColor( "#fffffd" );
   Int_t c_TitleBox  = TColor::GetColor( "#6D7B8D" );
   Int_t c_TitleText = TColor::GetColor( "#FFFFFF" );

   c1->SetFrameFillColor( c_FrameFill );
   c1->SetFillColor     ( c_Canvas    );
   c1->Divide(1,2);
   TVirtualPad * c11 = c1->cd(1);
   c11->SetFrameFillColor( c_FrameFill );
   c11->SetFillColor     ( c_Canvas    );

   gStyle->SetTitleFillColor( c_TitleBox  );
   gStyle->SetTitleTextColor( c_TitleText );
   gStyle->SetTitleBorderSize( 1 );
   gStyle->SetTitleH( 0.052 );
   gStyle->SetTitleX( c1->GetLeftMargin() );
   gStyle->SetTitleY( 1 - c1->GetTopMargin() + gStyle->GetTitleH() );
   gStyle->SetTitleW( 1 - c1->GetLeftMargin() - c1->GetRightMargin() );

   TH1D* frame = new TH1D( *unfres );
   frame->SetTitle( "Unfolding toy example with TSVDUnfold" );
   frame->GetXaxis()->SetTitle( "x variable" );
   frame->GetYaxis()->SetTitle( "Events" );
   frame->GetXaxis()->SetTitleOffset( 1.25 );
   frame->GetYaxis()->SetTitleOffset( 1.29 );
   frame->Draw();

   data->SetLineStyle(2);
   data->SetLineColor(4);
   data->SetLineWidth(2);
   unfres->SetMarkerStyle(20);
   datatrue->SetLineColor(2);
   datatrue->SetLineWidth(2);
   xini->SetLineStyle(2);
   xini->SetLineColor(8);
   xini->SetLineWidth(2);
   // ------------------------------------------------------------

   // add histograms
   unfres->Draw("same");
   datatrue->Draw("same");
   data->Draw("same");
   xini->Draw("same");

   leg->Draw();

   // covariance matrix
   gStyle->SetPalette(1,0);
   TVirtualPad * c12 = c1->cd(2);
   c12->Divide(2,1);
   TVirtualPad * c2 = c12->cd(1);
   c2->SetFrameFillColor( c_FrameFill );
   c2->SetFillColor     ( c_Canvas    );
   c2->SetRightMargin   ( 0.15         );

   TH2D* covframe = new TH2D( *ustatcov );
   covframe->SetTitle( "TSVDUnfold covariance matrix" );
   covframe->GetXaxis()->SetTitle( "x variable" );
   covframe->GetYaxis()->SetTitle( "x variable" );
   covframe->GetXaxis()->SetTitleOffset( 1.25 );
   covframe->GetYaxis()->SetTitleOffset( 1.29 );
   covframe->Draw();

   ustatcov->SetLineWidth( 2 );
   ustatcov->Draw( "colzsame" );

   // distribution of the d quantity
   TVirtualPad * c3 = c12->cd(2);
   c3->SetFrameFillColor( c_FrameFill );
   c3->SetFillColor     ( c_Canvas    );
   c3->SetLogy();

   TLine *line = new TLine( 0.,1.,40.,1. );
   line->SetLineStyle(2);

   TH1D* dframe = new TH1D( *ddist );
   dframe->SetTitle( "TSVDUnfold |d_{i}|" );
   dframe->GetXaxis()->SetTitle( "i" );
   dframe->GetYaxis()->SetTitle( "|d_{i}|" );
   dframe->GetXaxis()->SetTitleOffset( 1.25 );
   dframe->GetYaxis()->SetTitleOffset( 1.29 );
   dframe->SetMinimum( 0.001 );
   dframe->Draw();

   ddist->SetLineWidth( 2 );
   ddist->Draw( "same" );
   line->Draw();
}
 TSVDUnfoldExample.C:1
 TSVDUnfoldExample.C:2
 TSVDUnfoldExample.C:3
 TSVDUnfoldExample.C:4
 TSVDUnfoldExample.C:5
 TSVDUnfoldExample.C:6
 TSVDUnfoldExample.C:7
 TSVDUnfoldExample.C:8
 TSVDUnfoldExample.C:9
 TSVDUnfoldExample.C:10
 TSVDUnfoldExample.C:11
 TSVDUnfoldExample.C:12
 TSVDUnfoldExample.C:13
 TSVDUnfoldExample.C:14
 TSVDUnfoldExample.C:15
 TSVDUnfoldExample.C:16
 TSVDUnfoldExample.C:17
 TSVDUnfoldExample.C:18
 TSVDUnfoldExample.C:19
 TSVDUnfoldExample.C:20
 TSVDUnfoldExample.C:21
 TSVDUnfoldExample.C:22
 TSVDUnfoldExample.C:23
 TSVDUnfoldExample.C:24
 TSVDUnfoldExample.C:25
 TSVDUnfoldExample.C:26
 TSVDUnfoldExample.C:27
 TSVDUnfoldExample.C:28
 TSVDUnfoldExample.C:29
 TSVDUnfoldExample.C:30
 TSVDUnfoldExample.C:31
 TSVDUnfoldExample.C:32
 TSVDUnfoldExample.C:33
 TSVDUnfoldExample.C:34
 TSVDUnfoldExample.C:35
 TSVDUnfoldExample.C:36
 TSVDUnfoldExample.C:37
 TSVDUnfoldExample.C:38
 TSVDUnfoldExample.C:39
 TSVDUnfoldExample.C:40
 TSVDUnfoldExample.C:41
 TSVDUnfoldExample.C:42
 TSVDUnfoldExample.C:43
 TSVDUnfoldExample.C:44
 TSVDUnfoldExample.C:45
 TSVDUnfoldExample.C:46
 TSVDUnfoldExample.C:47
 TSVDUnfoldExample.C:48
 TSVDUnfoldExample.C:49
 TSVDUnfoldExample.C:50
 TSVDUnfoldExample.C:51
 TSVDUnfoldExample.C:52
 TSVDUnfoldExample.C:53
 TSVDUnfoldExample.C:54
 TSVDUnfoldExample.C:55
 TSVDUnfoldExample.C:56
 TSVDUnfoldExample.C:57
 TSVDUnfoldExample.C:58
 TSVDUnfoldExample.C:59
 TSVDUnfoldExample.C:60
 TSVDUnfoldExample.C:61
 TSVDUnfoldExample.C:62
 TSVDUnfoldExample.C:63
 TSVDUnfoldExample.C:64
 TSVDUnfoldExample.C:65
 TSVDUnfoldExample.C:66
 TSVDUnfoldExample.C:67
 TSVDUnfoldExample.C:68
 TSVDUnfoldExample.C:69
 TSVDUnfoldExample.C:70
 TSVDUnfoldExample.C:71
 TSVDUnfoldExample.C:72
 TSVDUnfoldExample.C:73
 TSVDUnfoldExample.C:74
 TSVDUnfoldExample.C:75
 TSVDUnfoldExample.C:76
 TSVDUnfoldExample.C:77
 TSVDUnfoldExample.C:78
 TSVDUnfoldExample.C:79
 TSVDUnfoldExample.C:80
 TSVDUnfoldExample.C:81
 TSVDUnfoldExample.C:82
 TSVDUnfoldExample.C:83
 TSVDUnfoldExample.C:84
 TSVDUnfoldExample.C:85
 TSVDUnfoldExample.C:86
 TSVDUnfoldExample.C:87
 TSVDUnfoldExample.C:88
 TSVDUnfoldExample.C:89
 TSVDUnfoldExample.C:90
 TSVDUnfoldExample.C:91
 TSVDUnfoldExample.C:92
 TSVDUnfoldExample.C:93
 TSVDUnfoldExample.C:94
 TSVDUnfoldExample.C:95
 TSVDUnfoldExample.C:96
 TSVDUnfoldExample.C:97
 TSVDUnfoldExample.C:98
 TSVDUnfoldExample.C:99
 TSVDUnfoldExample.C:100
 TSVDUnfoldExample.C:101
 TSVDUnfoldExample.C:102
 TSVDUnfoldExample.C:103
 TSVDUnfoldExample.C:104
 TSVDUnfoldExample.C:105
 TSVDUnfoldExample.C:106
 TSVDUnfoldExample.C:107
 TSVDUnfoldExample.C:108
 TSVDUnfoldExample.C:109
 TSVDUnfoldExample.C:110
 TSVDUnfoldExample.C:111
 TSVDUnfoldExample.C:112
 TSVDUnfoldExample.C:113
 TSVDUnfoldExample.C:114
 TSVDUnfoldExample.C:115
 TSVDUnfoldExample.C:116
 TSVDUnfoldExample.C:117
 TSVDUnfoldExample.C:118
 TSVDUnfoldExample.C:119
 TSVDUnfoldExample.C:120
 TSVDUnfoldExample.C:121
 TSVDUnfoldExample.C:122
 TSVDUnfoldExample.C:123
 TSVDUnfoldExample.C:124
 TSVDUnfoldExample.C:125
 TSVDUnfoldExample.C:126
 TSVDUnfoldExample.C:127
 TSVDUnfoldExample.C:128
 TSVDUnfoldExample.C:129
 TSVDUnfoldExample.C:130
 TSVDUnfoldExample.C:131
 TSVDUnfoldExample.C:132
 TSVDUnfoldExample.C:133
 TSVDUnfoldExample.C:134
 TSVDUnfoldExample.C:135
 TSVDUnfoldExample.C:136
 TSVDUnfoldExample.C:137
 TSVDUnfoldExample.C:138
 TSVDUnfoldExample.C:139
 TSVDUnfoldExample.C:140
 TSVDUnfoldExample.C:141
 TSVDUnfoldExample.C:142
 TSVDUnfoldExample.C:143
 TSVDUnfoldExample.C:144
 TSVDUnfoldExample.C:145
 TSVDUnfoldExample.C:146
 TSVDUnfoldExample.C:147
 TSVDUnfoldExample.C:148
 TSVDUnfoldExample.C:149
 TSVDUnfoldExample.C:150
 TSVDUnfoldExample.C:151
 TSVDUnfoldExample.C:152
 TSVDUnfoldExample.C:153
 TSVDUnfoldExample.C:154
 TSVDUnfoldExample.C:155
 TSVDUnfoldExample.C:156
 TSVDUnfoldExample.C:157
 TSVDUnfoldExample.C:158
 TSVDUnfoldExample.C:159
 TSVDUnfoldExample.C:160
 TSVDUnfoldExample.C:161
 TSVDUnfoldExample.C:162
 TSVDUnfoldExample.C:163
 TSVDUnfoldExample.C:164
 TSVDUnfoldExample.C:165
 TSVDUnfoldExample.C:166
 TSVDUnfoldExample.C:167
 TSVDUnfoldExample.C:168
 TSVDUnfoldExample.C:169
 TSVDUnfoldExample.C:170
 TSVDUnfoldExample.C:171
 TSVDUnfoldExample.C:172
 TSVDUnfoldExample.C:173
 TSVDUnfoldExample.C:174
 TSVDUnfoldExample.C:175
 TSVDUnfoldExample.C:176
 TSVDUnfoldExample.C:177
 TSVDUnfoldExample.C:178
 TSVDUnfoldExample.C:179
 TSVDUnfoldExample.C:180
 TSVDUnfoldExample.C:181
 TSVDUnfoldExample.C:182
 TSVDUnfoldExample.C:183
 TSVDUnfoldExample.C:184
 TSVDUnfoldExample.C:185
 TSVDUnfoldExample.C:186
 TSVDUnfoldExample.C:187
 TSVDUnfoldExample.C:188
 TSVDUnfoldExample.C:189
 TSVDUnfoldExample.C:190
 TSVDUnfoldExample.C:191
 TSVDUnfoldExample.C:192
 TSVDUnfoldExample.C:193
 TSVDUnfoldExample.C:194
 TSVDUnfoldExample.C:195
 TSVDUnfoldExample.C:196
 TSVDUnfoldExample.C:197
 TSVDUnfoldExample.C:198
 TSVDUnfoldExample.C:199
 TSVDUnfoldExample.C:200
 TSVDUnfoldExample.C:201
 TSVDUnfoldExample.C:202
 TSVDUnfoldExample.C:203
 TSVDUnfoldExample.C:204
 TSVDUnfoldExample.C:205
 TSVDUnfoldExample.C:206
 TSVDUnfoldExample.C:207
 TSVDUnfoldExample.C:208
 TSVDUnfoldExample.C:209
 TSVDUnfoldExample.C:210
 TSVDUnfoldExample.C:211
 TSVDUnfoldExample.C:212
 TSVDUnfoldExample.C:213
 TSVDUnfoldExample.C:214
 TSVDUnfoldExample.C:215
 TSVDUnfoldExample.C:216
 TSVDUnfoldExample.C:217
 TSVDUnfoldExample.C:218
 TSVDUnfoldExample.C:219
 TSVDUnfoldExample.C:220
 TSVDUnfoldExample.C:221
 TSVDUnfoldExample.C:222
 TSVDUnfoldExample.C:223
 TSVDUnfoldExample.C:224
 TSVDUnfoldExample.C:225
 TSVDUnfoldExample.C:226
 TSVDUnfoldExample.C:227
 TSVDUnfoldExample.C:228
 TSVDUnfoldExample.C:229
 TSVDUnfoldExample.C:230
 TSVDUnfoldExample.C:231
 TSVDUnfoldExample.C:232
 TSVDUnfoldExample.C:233
 TSVDUnfoldExample.C:234
 TSVDUnfoldExample.C:235
 TSVDUnfoldExample.C:236
 TSVDUnfoldExample.C:237
 TSVDUnfoldExample.C:238
 TSVDUnfoldExample.C:239
 TSVDUnfoldExample.C:240
 TSVDUnfoldExample.C:241
 TSVDUnfoldExample.C:242
 TSVDUnfoldExample.C:243
 TSVDUnfoldExample.C:244
 TSVDUnfoldExample.C:245
 TSVDUnfoldExample.C:246
 TSVDUnfoldExample.C:247
 TSVDUnfoldExample.C:248
 TSVDUnfoldExample.C:249
 TSVDUnfoldExample.C:250
 TSVDUnfoldExample.C:251
 TSVDUnfoldExample.C:252
 TSVDUnfoldExample.C:253