From 800ab70976d7a7d52d9b608d42db02530282cb14 Mon Sep 17 00:00:00 2001 From: Lorenzo Moneta <Lorenzo.Moneta@cern.ch> Date: Tue, 30 Nov 2010 13:30:14 +0000 Subject: [PATCH] from Kerstin Tackmann and Andreas Hoecker: newt tutorial for the TSVUnfold class git-svn-id: http://root.cern.ch/svn/root/trunk@37101 27541ba8-7e3a-0410-8455-c3a389f83636 --- tutorials/math/TSVDUnfoldExample.C | 240 +++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 tutorials/math/TSVDUnfoldExample.C diff --git a/tutorials/math/TSVDUnfoldExample.C b/tutorials/math/TSVDUnfoldExample.C new file mode 100644 index 00000000000..9d4ceab2ee9 --- /dev/null +++ b/tutorials/math/TSVDUnfoldExample.C @@ -0,0 +1,240 @@ +////////////////////////////////////////////////////////////////////////// +// // +// 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, 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 + // 1000 toys is usually reasonable + TH2D* ustatcov = tsvdunf->GetUnfoldCovMatrix( statcov, 1000 ); + + // Now compute the error matrix on the unfolded distribution originating + // from the finite detector matrix statistics + TH2D* uadetcov = tsvdunf->GetAdetCovMatrix( 1000 ); + + // Sum up the two (they are uncorrelated) + ustatcov->Add( uadetcov ); + + // --- Only plotting stuff below ------------------------------ + + for (int i=1; i<=unfres->GetNbinsX(); i++) { + unfres->SetBinError(i, TMath::Sqrt(ustatcov->GetBinContent(i,i))); + } + + 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); + c1->cd(1); + + + 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(); + + + // distribution of the d quantity + gStyle->SetOptLogy(); + TVirtualPad * c12 = c1->cd(2); + c12->Divide(2,1); + TVirtualPad * c2 = c12->cd(1); + c2->SetFrameFillColor( c_FrameFill ); + c2->SetFillColor ( c_Canvas ); + + TLine *line = new TLine( 0.,1.,40.,1. ); + line->SetLineStyle(2); + + TH1D* dframe = new TH1D( *ddist ); + dframe->SetTitle( "TSVDUnfold |d_{i}| for toy example" ); + 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(); + + // distribution of the singular values + gStyle->SetOptLogy(); + TVirtualPad * c3 = c12->cd(2); + c3->SetFrameFillColor( c_FrameFill ); + c3->SetFillColor ( c_Canvas ); + + TH1D* svframe = new TH1D( *svdist ); + svframe->SetTitle( "TSVDUnfold singular values for toy example" ); + svframe->GetXaxis()->SetTitle( "i" ); + svframe->GetYaxis()->SetTitle( "|s_{i}|" ); + svframe->GetXaxis()->SetTitleOffset( 1.25 ); + svframe->GetYaxis()->SetTitleOffset( 1.29 ); + svframe->SetMinimum( 0.001 ); + svframe->Draw(); + + svdist->SetLineWidth( 2 ); + svdist->Draw( "same" ); + //c1->Print("TSVDUnfoldExample.pdf"); +} -- GitLab