File indexing completed on 2024-04-06 12:22:44
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <iostream>
0016 #include "TFile.h"
0017 #include "TH1F.h"
0018 #include "TCanvas.h"
0019 #include "TF1.h"
0020 #include "TLegend.h"
0021 #include <vector>
0022 #include "TString.h"
0023 #include <sstream>
0024
0025
0026
0027
0028 class Linear
0029 {
0030 public:
0031 Linear(const double & lowerLimit, const double & upperLimit) : lowerLimit_(lowerLimit), upperLimit_(upperLimit) {}
0032
0033 double operator()( const double * x, const double * parval ) const
0034 {
0035 double a = parval[1];
0036 double b = parval[2];
0037
0038 double norm = -(a*lowerLimit_ + b*lowerLimit_*lowerLimit_/2.);
0039
0040 if( -a/b > upperLimit_ ) norm += a*upperLimit_ + b*upperLimit_*upperLimit_/2.;
0041 else norm += -a*a/(2*b);
0042
0043 if( x[0] < -a/b && norm != 0 ) return (a + b*x[0])/norm;
0044 else return 0;
0045 }
0046 protected:
0047 double lowerLimit_, upperLimit_;
0048 };
0049
0050 class Atan
0051 {
0052 public:
0053 Atan(const double & lowerLimit, const double & upperLimit) : lowerLimit_(lowerLimit), upperLimit_(upperLimit) {}
0054
0055 double operator()( const double * x, const double * parval ) const
0056 {
0057 double value = atan(parval[1]*(x[0] + parval[2]));
0058 double upperX = parval[1]*(upperLimit_ + parval[2]);
0059 double lowerX = parval[1]*(lowerLimit_ + parval[2]);
0060 double norm = (upperX*atan(upperX) - 0.5*log(1+upperX*upperX) - (lowerX*atan(lowerX) - 0.5*log(1+lowerX*lowerX)))/parval[1];
0061
0062 if( norm != 0 ) return value/norm;
0063 return 0.;
0064 }
0065 protected:
0066 double lowerLimit_, upperLimit_;
0067 };
0068
0069 TH1F * subRangeHisto( const double * resMass, const double * resHalfWidth,
0070 const int iRes, TH1F * histo, const TString & name )
0071 {
0072 std::stringstream ss;
0073 ss << iRes;
0074
0075 TH1F* newHisto = (TH1F*)histo->Clone(name+ss.str());
0076 newHisto->SetAxisRange( resMass[iRes] - resHalfWidth[iRes], resMass[iRes] + resHalfWidth[iRes] );
0077
0078 if( iRes == 3 ) {
0079 newHisto->SetAxisRange( resMass[iRes] - resHalfWidth[iRes], resMass[1] + resHalfWidth[iRes] );
0080 }
0081 return newHisto;
0082 }
0083
0084 TH1F * buildHistogram(const double * ResMass, const double * ResHalfWidth, const int xBins, const double & deltaX, const double & xMin, const double & xMax,
0085 const int ires, const double & Bgrp1, const double & a, const double & leftWindowBorder, const double & rightWindowBorder,
0086 const TH1F* allHisto, const int backgroundType, const double & b = 0);
0087
0088 void BackgroundCheck()
0089 {
0090 TFile * allFile = new TFile("0_MuScleFit.root", "READ");
0091 TFile * resonanceFile = new TFile("0_MuScleFit.root", "READ");
0092 TFile * backgroundFile = new TFile("0_MuScleFit.root", "READ");
0093
0094
0095 TH1F * allHisto = (TH1F*)allFile->Get("hRecBestResAllEvents_Mass");
0096 TH1F * resonanceHisto = (TH1F*)resonanceFile->Get("hRecBestRes_Mass");
0097 TH1F * backgroundHisto = (TH1F*)backgroundFile->Get("hRecBestRes_Mass");
0098
0099 int rebinCount = 4;
0100
0101 allHisto->Rebin(rebinCount);
0102 resonanceHisto->Rebin(rebinCount);
0103 backgroundHisto->Rebin(rebinCount);
0104
0105 double xMin = allHisto->GetXaxis()->GetXmin();
0106 double xMax = allHisto->GetXaxis()->GetXmax();
0107 double deltaX = xMax - xMin;
0108
0109
0110
0111 int xBins = allHisto->GetNbinsX();
0112
0113 double OriginalResMass[] = {91.1876, 10.3552, 10.0233, 9.4603, 3.68609, 3.096916};
0114 double ResMass[] = {91.1876, 0., 0., (10.3552 + 10.0233 + 9.4603)/3., (3.68609 + 3.096916)/2., (3.68609 + 3.096916)/2.};
0115 double ResHalfWidth[] = {20., 0.5, 0.5, 0.5, 0.2, 0.2};
0116 TString ResName[] = {"Z", "Upsilon3S", "Upsilon2S", "Upsilon1S", "Psi2S", "J/Psi"};
0117
0118 std::vector<int> ires;
0119 std::vector<double> Bgrp1;
0120 std::vector<double> a;
0121 std::vector<double> leftWindowBorder;
0122 std::vector<double> rightWindowBorder;
0123 int backgroundType = 0;
0124
0125
0126
0127 ires.push_back(5);
0128
0129
0130 backgroundType = 0;
0131 Bgrp1.push_back(0.730566);
0132 a.push_back(0.826053);
0133 a.push_back(0);
0134 leftWindowBorder.push_back(2.5);
0135 rightWindowBorder.push_back(5.);
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156 std::vector<TH1F*> backgroundFunctionHisto;
0157 for( unsigned int i=0; i<ires.size(); ++i ) {
0158 backgroundFunctionHisto.push_back( buildHistogram(ResMass, ResHalfWidth, xBins, deltaX, xMin, xMax,
0159 ires[i], Bgrp1[i], a[i], leftWindowBorder[i], rightWindowBorder[i],
0160 allHisto, backgroundType, a[i+1]) );
0161 }
0162
0163 TLegend * legend = new TLegend( 0.55, 0.65, 0.76, 0.82 );
0164 TCanvas * canvas = new TCanvas("ResMassCanvas", "ResMassCanvas", 1000, 800);
0165 canvas->cd();
0166 legend->AddEntry(allHisto, "All events");
0167 allHisto->SetLineWidth(2);
0168 allHisto->Draw();
0169
0170 resonanceHisto->SetLineColor(kRed);
0171 resonanceHisto->SetLineWidth(2);
0172 resonanceHisto->Draw("same");
0173 legend->AddEntry(resonanceHisto, "Resonance events");
0174
0175 backgroundHisto->SetLineWidth(2);
0176 backgroundHisto->SetLineColor(kBlue);
0177 backgroundHisto->Draw("same");
0178 legend->AddEntry(backgroundHisto, "Background events");
0179
0180 for( unsigned int i=0; i<ires.size(); ++i ) {
0181 backgroundFunctionHisto[i]->SetLineWidth(2);
0182 if( i == 1 ) backgroundFunctionHisto[i]->SetLineColor(kRed);
0183 else backgroundFunctionHisto[i]->SetLineColor(kGreen);
0184
0185 backgroundFunctionHisto[i]->Draw("same");
0186
0187 TH1F * whiteHisto = subRangeHisto(OriginalResMass, ResHalfWidth, ires[i], backgroundFunctionHisto[i], "whiteHisto");
0188 whiteHisto->SetLineWidth(2);
0189 whiteHisto->SetLineColor(kWhite);
0190 whiteHisto->Draw("same");
0191
0192 TH1F * dashedHisto = subRangeHisto(OriginalResMass, ResHalfWidth, ires[i], backgroundFunctionHisto[i], "dashedHisto");
0193 dashedHisto->SetLineWidth(2);
0194 dashedHisto->SetLineStyle(7);
0195 dashedHisto->Draw("same");
0196
0197 legend->AddEntry(backgroundFunctionHisto[i], "Background function for "+ResName[ires[i]]);
0198 }
0199
0200 legend->Draw("same");
0201
0202 canvas->GetPad(0)->SetLogy(true);
0203
0204 canvas->Print("BackgroundCheck.pdf");
0205 }
0206
0207 TH1F * buildHistogram(const double * ResMass, const double * ResHalfWidth, const int xBins,
0208 const double & deltaX, const double & xMin, const double & xMax,
0209 const int ires, const double & Bgrp1, const double & a,
0210 const double & leftWindowBorder, const double & rightWindowBorder,
0211 const TH1F* allHisto, const int backgroundType, const double & b)
0212 {
0213
0214 double lowWindowValue = leftWindowBorder;
0215 double upWindowValue = rightWindowBorder;
0216
0217 int lowBin = int((lowWindowValue)*xBins/deltaX);
0218 int upBin = int((upWindowValue)*xBins/deltaX);
0219
0220 std::cout << "lowBin = " << lowBin << ", upBin = " << upBin << std::endl;
0221 std::cout << "lowWindowValue = " << lowWindowValue << ", upWindowValue = " << upWindowValue << std::endl;
0222
0223 double xWidth = deltaX/xBins;
0224
0225
0226 TF1 * backgroundFunction = 0;
0227 TH1F * backgroundFunctionHisto = 0;
0228
0229 if( backgroundType == 0 ) {
0230
0231
0232
0233 std::stringstream ssUp;
0234 std::stringstream ssDown;
0235 ssUp << upWindowValue;
0236 ssDown << lowWindowValue;
0237 std::string functionString("[0]*(-[1]*exp(-[1]*x)/(exp(-[1]*("+ssUp.str()+")) - exp(-[1]*("+ssDown.str()+")) ))");
0238
0239 backgroundFunction = new TF1("backgroundFunction", functionString.c_str(), xMin, xMax );
0240 backgroundFunction->SetParameter(0, 1);
0241 backgroundFunction->SetParameter(1, a);
0242 backgroundFunctionHisto = new TH1F("backgroundFunctionHisto", "backgroundFunctionHisto", xBins, xMin, xMax);
0243 for( int xBin = 0; xBin < xBins; ++xBin ) {
0244 backgroundFunctionHisto->SetBinContent(xBin+1, backgroundFunction->Integral(xBin*xWidth, (xBin+1)*xWidth));
0245 }
0246 }
0247 else if( backgroundType == 2 ) {
0248
0249 std::stringstream ssUp;
0250 std::stringstream ssDown;
0251 ssUp << upWindowValue;
0252 ssDown << lowWindowValue;
0253
0254 Atan * atanFunction = new Atan(lowWindowValue, upWindowValue);
0255 backgroundFunction = new TF1("backgroundFunction", atanFunction, 0, 1, 3, "atanFunction");
0256
0257 backgroundFunction->SetParameter(0, 1);
0258 backgroundFunction->SetParameter(1, a);
0259 backgroundFunction->SetParameter(2, b);
0260 backgroundFunctionHisto = new TH1F("backgroundFunctionHisto", "backgroundFunctionHisto", xBins, xMin, xMax);
0261 for( int xBin = 0; xBin < xBins; ++xBin ) {
0262 backgroundFunctionHisto->SetBinContent(xBin+1, backgroundFunction->Integral(xBin*xWidth, (xBin+1)*xWidth));
0263 }
0264 }
0265 else {
0266
0267
0268 Linear * linearFunction = new Linear(lowWindowValue, upWindowValue);
0269 backgroundFunction = new TF1("backgroundFunction", linearFunction, 0, 1, 3, "linearFunction");
0270 backgroundFunction->SetParameter(0, 1);
0271 backgroundFunction->SetParameter(1, a);
0272 backgroundFunction->SetParameter(2, b);
0273 backgroundFunctionHisto = new TH1F("backgroundFunctionHisto", "backgroundFunctionHisto", xBins, xMin, xMax);
0274 for( int xBin = 0; xBin < xBins; ++xBin ) {
0275 backgroundFunctionHisto->SetBinContent(xBin+1, backgroundFunction->Integral(xBin*xWidth, (xBin+1)*xWidth));
0276 }
0277 }
0278
0279
0280
0281 double totEvents = allHisto->Integral(lowBin, upBin);
0282 backgroundFunctionHisto->Scale(Bgrp1*totEvents);
0283 backgroundFunction->SetParameter(0, Bgrp1*totEvents);
0284
0285 std::cout << "Total events in the background window = " << totEvents << std::endl;
0286 std::cout << "FunctionHisto integral = " << backgroundFunctionHisto->Integral(lowBin, upBin) << std::endl;
0287 std::cout << "Function integral = " << backgroundFunction->Integral(lowWindowValue, upWindowValue) << std::endl;
0288
0289 backgroundFunctionHisto->SetAxisRange(lowWindowValue, upWindowValue);
0290
0291 return backgroundFunctionHisto;
0292 }