File indexing completed on 2025-08-05 08:12:56
0001 #include <string>
0002 #include <iostream>
0003 #include <sstream>
0004 #include <cmath>
0005 #ifndef __CINT__
0006 #include <RooGlobalFunc.h>
0007 #endif
0008 #include <RooRealVar.h>
0009 #include <RooDataSet.h>
0010 #include <RooDataHist.h>
0011 #include <RooGaussian.h>
0012 #include <RooBifurGauss.h>
0013
0014 #include <RooHist.h>
0015 #include <RooPlot.h>
0016 #include <RooExponential.h>
0017 #include <RooAddPdf.h>
0018 #include <RooStats/SPlot.h>
0019 #include <TH1F.h>
0020 #include <TFile.h>
0021 #include <TTree.h>
0022 #include <TCut.h>
0023 #include <TChain.h>
0024 #include <TMath.h>
0025 #include <TPad.h>
0026 #include <TCanvas.h>
0027 #include <TBranch.h>
0028
0029 using namespace RooFit;
0030 using namespace std;
0031
0032
0033 std::string getDate()
0034 {
0035 std::time_t t = std::time(0);
0036 std::tm* now = std::localtime(&t);
0037
0038 std::stringstream date;
0039 date << (now->tm_mon + 1) << '/'
0040 << now->tm_mday << '/'
0041 << (now->tm_year + 1900);
0042 return date.str();
0043 }
0044
0045 template <typename T>
0046 string to_string_with_precision(const T a_value, const int n = 2)
0047 {
0048 ostringstream out;
0049 out.precision(n);
0050 out << fixed << a_value;
0051 return out.str();
0052 }
0053
0054 void D0_fitter_QM25()
0055 {
0056
0057 string changeType[] = {"optimized"};
0058
0059 int maxDigits = 3;
0060 TGaxis::SetMaxDigits(maxDigits);
0061
0062 string path, inputFile, plotTitle, saveName, xAxisTitle, branch, dataType;
0063 double minMass = 1.7;
0064 double maxMass = 2.0;
0065
0066 path = "/sphenix/user/cdean/public/QM25/";
0067
0068 for (auto change : changeType)
0069 {
0070 inputFile = path + "output_D0_oldKFP_ana475p017_optimized.root";
0071 dataType = "pp";
0072
0073 branch = "D0_mass";
0074 plotTitle = "";
0075 saveName = path + "fits/D02Kpi_ana475p01_optimized";
0076 xAxisTitle = "m(K^{#mp}#pi^{#pm}) [GeV]";
0077
0078 stringstream cutStream;
0079 cutStream << minMass << " <= " << branch << " && " << branch << " <= " << maxMass;
0080 TCut masscut = cutStream.str().c_str();
0081
0082
0083
0084
0085
0086 TFile* dataFile = new TFile(inputFile.c_str());
0087 TTree* dataTree = (TTree*)dataFile->Get("DecayTree");
0088
0089 string datasWeight = inputFile.substr(0, inputFile.size()-5) + "_weighted.root";
0090 TFile* sWeightedDataFile = new TFile(datasWeight.c_str(), "RECREATE");
0091 TTree* dataCopyTree = dataTree->CopyTree(masscut);
0092 TTree* dataCloneTree = dataCopyTree->CloneTree(-1);
0093
0094 RooRealVar mass(branch.c_str(), "mass", minMass, maxMass);
0095 RooDataSet dataSet(branch.c_str(), "data", mass, Import(*dataCloneTree));
0096
0097
0098
0099
0100
0101 RooRealVar mean("D0_mean", "mean", 1.864, 1.855, 1.875);
0102
0103
0104 RooRealVar sigma("sigma", "sigma", 0.01, 0.000, 0.02);
0105 RooGaussian signal("signal", "signal", mass, mean, sigma);
0106
0107 RooRealVar fSig("fSig", "fSig", 0.*dataSet.numEntries(), 0., 0.1*dataSet.numEntries());
0108 RooRealVar fBkg("fBkg", "fBkg", 0.*dataSet.numEntries(), 0., 1*dataSet.numEntries());
0109
0110
0111
0112
0113
0114 RooRealVar expConstOne("expConstOne", "expConstOne", -10, -1e2, 0.);
0115 RooExponential background("background", "background", mass, expConstOne);
0116
0117
0118
0119
0120
0121 RooArgList fitModelList(signal, background), fitFracList(fSig);
0122 RooAddPdf model("model", "model", fitModelList, fitFracList);
0123 model.fitTo(dataSet);
0124
0125 RooPlot* frame = mass.frame(Title(plotTitle.c_str()));
0126
0127 RooBinning bins(minMass, maxMass);
0128 int nBins = 25;
0129 bins.addUniform(nBins, minMass, maxMass);
0130
0131 dataSet.plotOn(frame, Binning(bins), XErrorSize(0), DataError(RooAbsData::SumW2));
0132 model.plotOn(frame, Components(background), LineColor(kGray), DrawOption("F"), FillColor(kGray));
0133 model.plotOn(frame, Components(RooArgSet(signal, background)), LineColor(kAzure+8), DrawOption("F"), FillColor(kAzure+8), MoveToBack());
0134 model.plotOn(frame, LineColor(kBlack));
0135 dataSet.plotOn(frame, DrawOption("PE1"), Binning(bins),XErrorSize(0), DataError(RooAbsData::SumW2));
0136
0137
0138 RooHist* pull = frame->pullHist();
0139 RooPlot* frame2 = mass.frame(Title(""));
0140 frame2->addPlotable(pull,"PE1");
0141
0142 TCanvas* c = new TCanvas("massFitCanvas", "massFitCanvas",800, 800);
0143
0144 TPad mainPad("mainPad", "mainPad", 0., 0.3, 1., 1.);
0145 mainPad.SetBottomMargin(0);
0146 mainPad.Draw();
0147
0148 TPad pullPad("pullPad", "pullPad", 0., 0.0, 1., 0.3);
0149 pullPad.SetBottomMargin(0.5);
0150 pullPad.SetTopMargin(0);
0151
0152 pullPad.Draw();
0153
0154 mainPad.cd();
0155
0156 frame->SetMarkerStyle(kCircle);
0157 frame->SetMarkerSize(0.02);
0158 frame->SetLineWidth(1);
0159 frame->GetXaxis()->SetTitleSize(0);
0160 frame->GetXaxis()->SetLabelSize(0);
0161 frame->GetYaxis()->SetTitleFont(42);
0162 frame->GetYaxis()->SetLabelFont(42);
0163 frame->GetYaxis()->SetRangeUser(181, 580);
0164 float binWidth = 1000.*(maxMass - minMass) / nBins;
0165 string yAxisTitle = "Candidates / (" + to_string_with_precision(binWidth, 0) + " MeV)";
0166 frame->GetYaxis()->SetTitle(yAxisTitle.c_str());
0167 frame->Draw();
0168
0169
0170 string fitSigYield = to_string_with_precision(dataSet.numEntries() * fSig.getValV(), 0);
0171 string fitSigError = to_string_with_precision(dataSet.numEntries() * fSig.getError(), 0);
0172 string fitYield = "Yield = " + fitSigYield + "#pm " + fitSigError;
0173 double significance = fSig.getValV()/fSig.getError();
0174 string fitSignificance = "Significance = " + to_string_with_precision(significance, 1);
0175 int nEvents = dataCloneTree->GetEntries();
0176 cout << "*\n*\n* nEvents = " << nEvents << "\n* nSig = " << fitSigYield << " +/- " << fitSigError << endl;
0177 double chiSq = frame->chiSquare("model", "data", 4);
0178 cout << "* Fit chisq/ndf = " << chiSq << "\n*\n*" << endl;
0179
0180
0181 string fitMeanVal = to_string_with_precision(1e3 * mean.getValV(), 1);
0182 string fitMeanErr = to_string_with_precision(1e3 * mean.getError(), 1);
0183 string fitMean = "#mu = " + fitMeanVal + "#pm " + fitMeanErr + " MeV";
0184 string fitWidthVal = to_string_with_precision(1e3 * sigma.getValV(), 1);
0185 string fitWidthErr = to_string_with_precision(1e3 * sigma.getError(), 1);
0186 string fitWidth = "#sigma = " + fitWidthVal + "#pm " + fitWidthErr + " MeV";
0187
0188 TPaveText *pt;
0189 pt = new TPaveText(0.14,0.05,0.52,0.35, "NDC");
0190 pt->SetFillColor(0);
0191 pt->SetFillStyle(0);
0192 pt->SetTextFont(42);
0193 TText *pt_LaTex = pt->AddText("#it{#bf{sPHENIX}} Preliminary");
0194 pt_LaTex = pt->AddText("#it{p}+#it{p} #sqrt{s} = 200 GeV");
0195 pt_LaTex = pt->AddText("Early Calibration");
0196 pt_LaTex = pt->AddText(fitMean.c_str());
0197 pt_LaTex = pt->AddText(fitWidth.c_str());
0198 pt_LaTex = pt->AddText(fitYield.c_str());
0199
0200 pt->SetBorderSize(0);
0201 pt->DrawClone();
0202
0203
0204 TPaveText *ptDate;
0205 ptDate = new TPaveText(0.67,0.92,1.05,1.00, "NDC");
0206 ptDate->SetFillColor(0);
0207 ptDate->SetFillStyle(0);
0208 ptDate->SetTextFont(42);
0209 std::string compilation_date = getDate();
0210 TText *pt_LaTexDate = ptDate->AddText(compilation_date.c_str());
0211 ptDate->SetBorderSize(0);
0212 ptDate->Draw();
0213 gPad->Modified();
0214
0215 gPad->SetTopMargin(0.08);
0216
0217
0218 TLegend *legend = new TLegend(0.62,0.60,0.90,0.85);
0219 legend->AddEntry(frame->findObject("h_D0_mass"),"Data","PE2");
0220 legend->AddEntry(frame->findObject("model_Norm[D0_mass]"),"Fit","L");
0221 legend->AddEntry(frame->findObject("model_Norm[D0_mass]_Comp[signal,background]"),"D^{0}#rightarrow K^{-}#pi^{+} + c.c.","f");
0222 legend->AddEntry(frame->findObject("model_Norm[D0_mass]_Comp[background]"),"Comb. Bkg.","f");
0223 legend->SetFillColor(0);
0224 legend->SetFillStyle(0);
0225 legend->SetBorderSize(0);
0226 legend->SetTextSize(0.05);
0227 legend->Draw();
0228
0229 gPad->Modified();
0230 pullPad.cd();
0231
0232 frame2->SetMarkerStyle(kCircle);
0233 frame2->SetMarkerSize(0.02);
0234 frame2->SetTitle("");
0235 frame2->GetXaxis()->SetNdivisions(505);
0236 frame2->GetXaxis()->SetTitle(xAxisTitle.c_str());
0237 frame2->GetXaxis()->SetTitleOffset(0.9);
0238 frame2->GetXaxis()->SetTitleFont(42);
0239 frame2->GetXaxis()->SetTitleSize(0.12);
0240 frame2->GetXaxis()->SetLabelFont(42);
0241 frame2->GetXaxis()->SetLabelSize(0.12);
0242 frame2->GetYaxis()->SetTitle("Pull");
0243 frame2->GetYaxis()->SetTitleOffset(0.55);
0244 frame2->GetYaxis()->SetTitleFont(42);
0245 frame2->GetYaxis()->SetTitleSize(0.12);
0246 frame2->GetYaxis()->SetLabelFont(42);
0247 frame2->GetYaxis()->SetLabelSize(0.12);
0248 frame2->GetYaxis()->SetRangeUser(-6, 6);
0249 frame2->GetYaxis()->SetNdivisions(5);
0250 TF1 *plusThreeLine = new TF1("plusThreeLine", "pol1", minMass, maxMass);
0251 plusThreeLine->SetParameters(3, 0);
0252 plusThreeLine->SetLineColor(1);
0253 plusThreeLine->SetLineStyle(2);
0254 plusThreeLine->SetLineWidth(2);
0255 TF1 *zeroLine = new TF1("zeroLine", "pol1", minMass, maxMass);
0256 zeroLine->SetParameters(0, 0);
0257 zeroLine->SetLineColor(1);
0258 zeroLine->SetLineStyle(2);
0259 zeroLine->SetLineWidth(2);
0260 TF1 *minusThreeLine = new TF1("minusThreeLine", "pol1", minMass, maxMass);
0261 minusThreeLine->SetParameters(-3, 0);
0262 minusThreeLine->SetLineColor(1);
0263 minusThreeLine->SetLineStyle(2);
0264 minusThreeLine->SetLineWidth(2);
0265 frame2->Draw();
0266 plusThreeLine->Draw("same");
0267 zeroLine->Draw("same");
0268 minusThreeLine->Draw("same");
0269
0270 vector<string> extensions = {".C", ".pdf", ".png"};
0271 for (auto &extension : extensions)
0272 {
0273 string outputFile = saveName + "_" + dataType + extension;
0274 c->SaveAs(outputFile.c_str());
0275 }
0276 }
0277 }