//////////////////////////////////////////////////////////////////////////// // // // This program should be run under root: // // root fluxMUnfold.C++ // // // // Authors: T. Bretz 02/2002 // // W. Wittek 09/2002 // // R. Wagner 11/2004 // // // // this macro is prepared to be used in the analysis: // // // // the unfolding should be called by // // doUnfolding(TH2D &tobeunfolded, // (E-est, Theta) // // TH3D &migrationmatrix, // (E-est, E-true, Theta) // // TH2D &unfolded) // (E-true,Theta) // // // //////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include TH1 *DrawMatrixClone(const TMatrixD &m, Option_t *opt="") { const Int_t nrows = m.GetNrows(); const Int_t ncols = m.GetNcols(); TMatrix m2(nrows, ncols); for (int i=0; iSetBit(kCanDelete); hist->Draw(opt); hist->SetDirectory(NULL); return hist; } TH1 *DrawMatrixColClone(const TMatrixD &m, Option_t *opt="", Int_t col=0) { const Int_t nrows = m.GetNrows(); TVector vec(nrows); for (int i=0; iSetBinContent(i+1, vec(i)); } hist->SetBit(kCanDelete); hist->Draw(opt); hist->SetDirectory(NULL); return hist; } void PrintTH3Content(const TH3 &hist) { cout << hist.GetName() << ": " << hist.GetTitle() << endl; cout << "-----------------------------------------------------" << endl; for (Int_t i=1; i<=hist.GetNbinsX(); i++) { for (Int_t j=1; j<=hist.GetNbinsY(); j++) for (Int_t k=1; k<=hist.GetNbinsZ(); k++) cout << hist.GetBinContent(i,j,k) << " \t"; cout << endl << endl; } } void PrintTH3Error(const TH3 &hist) { cout << hist.GetName() << ": " << hist.GetTitle() << " " << endl; cout << "-----------------------------------------------------" << endl; for (Int_t i=1; i<=hist.GetNbinsX(); i++) { for (Int_t j=1; j<=hist.GetNbinsY(); j++) for (Int_t k=1; k<=hist.GetNbinsZ(); k++) cout << hist.GetBinError(i, j, k) << " \t"; cout << endl << endl; } } void PrintTH2Content(const TH2 &hist) { cout << hist.GetName() << ": " << hist.GetTitle() << endl; cout << "-----------------------------------------------------" << endl; for (Int_t i=1; i<=hist.GetNbinsX(); i++) for (Int_t j=1; j<=hist.GetNbinsY(); j++) cout << hist.GetBinContent(i,j) << " \t"; cout << endl << endl; } void PrintTH2Error(const TH2 &hist) { cout << hist.GetName() << ": " << hist.GetTitle() << " " << endl; cout << "-----------------------------------------------------" << endl; for (Int_t i=1; i<=hist.GetNbinsX(); i++) for (Int_t j=1; j<=hist.GetNbinsY(); j++) cout << hist.GetBinError(i, j) << " \t"; cout << endl << endl; } void PrintTH1Content(const TH1 &hist) { cout << hist.GetName() << ": " << hist.GetTitle() << endl; cout << "-----------------------------------------------------" << endl; for (Int_t i=1; i<=hist.GetNbinsX(); i++) cout << hist.GetBinContent(i) << " \t"; cout << endl << endl; } void PrintTH1Error(const TH1 &hist) { cout << hist.GetName() << ": " << hist.GetTitle() << " " << endl; cout << "-----------------------------------------------------" << endl; for (Int_t i=1; i<=hist.GetNbinsX(); i++) cout << hist.GetBinError(i) << " \t"; cout << endl << endl; } void CopyCol(TMatrixD &m, const TH1 &h, Int_t col=0) { const Int_t n = m.GetNrows(); for (Int_t i=0; i = a0 + a1*log10(Etrue) + a2*log10(Etrue)**2 // + log10(Etrue) // RMS( log10(Eest) ) = b0 + b1*log10(Etrue) + b2*log10(Etrue)**2 Double_t a0 = 0.0; Double_t a1 = 0.0; Double_t a2 = 0.0; Double_t b0 = 0.26; Double_t b1 =-0.054; Double_t b2 = 0.0; TF1 f2("f2", "gaus(0)", alow, aup); f2.SetParName(0, "ampl"); f2.SetParName(1, "mean"); f2.SetParName(2, "sigma"); // loop over log10(Etrue) bins TAxis &yaxis = *migration.GetYaxis(); for (Int_t j=1; j<=nb; j++) { Double_t yvalue = yaxis.GetBinCenter(j); const Double_t mean = a0 + a1*yvalue + a2*yvalue*yvalue + yvalue; const Double_t sigma = b0 + b1*yvalue + b2*yvalue*yvalue; const Double_t ampl = 1./ ( sigma*TMath::Sqrt(2.0*TMath::Pi())); // gaus(0) is a substitute for [0]*exp( -0.5*( (x-[1])/[2] )**2 ) f2.SetParameter(0, ampl); f2.SetParameter(1, mean); f2.SetParameter(2, sigma); // fill temporary 1-dim histogram with the function // fill the histogram using // - either FillRandom // - or using Freq TH1D htemp("temp", "temp", na, alow, aup); htemp.Sumw2(); for (Int_t k=0; k<1000000; k++) htemp.Fill(f2.GetRandom()); // copy it into the migration matrix Double_t sum = 0; for (Int_t i=1; i<=na; i++) { const Stat_t content = htemp.GetBinContent(i); migration.SetBinContent(i, j, m, content); sum += content; } // normalize migration matrix if (sum==0) continue; for (Int_t i=1; i<=na; i++) { const Stat_t content = migration.GetBinContent(i,j,m); migration.SetBinContent(i,j,m, content/sum); migration.SetBinError (i,j,m, sqrt(content)/sum); } } //PrintTH3Content(migration); //PrintTH3Error(migration); // ----------------------------------------- // ideal distribution TH1D hb0("hb0", "Ideal distribution", nb, blow, bup); hb0.Sumw2(); // fill histogram with random numbers according to // an exponential function dN/dE = E^{-gamma} // or with y = log10(E), E = 10^y : // dN/dy = ln10 * 10^{y*(1-gamma)} TF1 f1("f1", "pow(10.0, x*(1.0-[0]))", blow, bup); f1.SetParName(0,"gamma"); f1.SetParameter(0, 2.7); // ntimes is the number of entries for (Int_t k=0; k<10000; k++) hb0.Fill(f1.GetRandom()); // introduce energy threshold at 50 GeV const Double_t lgEth = 1.70; const Double_t dlgEth = 0.09; for (Int_t j=1; j<=nb; j++) { const Double_t lgE = hb0.GetBinCenter(j); const Double_t c = hb0.GetBinContent(j); const Double_t dc = hb0.GetBinError(j); const Double_t f = 1.0 / (1.0 + exp( -(lgE-lgEth)/dlgEth )); hb0.SetBinContent(j, f* c); hb0.SetBinError (j, f*dc); } //PrintTH1Content(hb0); // ----------------------------------------- // generate distribution to be unfolded (ha) // by smearing the ideal distribution (hb0) // TH2D tobeunfolded("tobeunfolded", "Distribution to be unfolded", na, alow, aup, nc, clow, cup); tobeunfolded.Sumw2(); for (Int_t i=1; i<=na; i++) { Double_t cont = 0; for (Int_t j=1; j<=nb; j++) cont += migration.GetBinContent(i, j, m) * hb0.GetBinContent(j); tobeunfolded.SetBinContent(i, m, cont); tobeunfolded.SetBinError(i, m, sqrt(cont)); } //PrintTH2Content(tobeunfolded); //PrintTH2Error(tobeunfolded); // ----------------------------------------- // unfolded distribution TH2D unfolded("unfolded", "Unfolded distribution", nb, blow, bup, nc, clow, cup); unfolded.Sumw2(); // ----------------------------------------- doUnfolding(tobeunfolded, migration, unfolded); } //========================================================================//