Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-07-16 08:11:24

0001 float lower_bin_bounds[] = {0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.8, 2.1, 2.4, 2.7, 3, 4};
0002 const unsigned int n_variable_bins = sizeof(lower_bin_bounds)/sizeof(lower_bin_bounds[0]) - 1; 
0003 
0004 string plotPath = "plots_looser_cuts/";
0005 
0006 const unsigned int Kshort_polynomial_order = 5;
0007 const unsigned int Lambda_polynomial_order = 8;
0008 
0009 struct fit_ranges
0010 {
0011   float min;
0012   float ignore_min;
0013   float ignore_max;
0014   float max;
0015 };
0016 
0017 fit_ranges Kshort_ranges{0.35, 0.47, 0.535, 0.65};
0018 fit_ranges Lambda_ranges{1.09, 1.105, 1.125, 1.15};
0019 
0020 float Kshort_xVals[n_variable_bins], Kshort_xErrs[n_variable_bins], Kshort_yVals[n_variable_bins], Kshort_yErrs[n_variable_bins];
0021 float Lambda_xVals[n_variable_bins], Lambda_xErrs[n_variable_bins], Lambda_yVals[n_variable_bins], Lambda_yErrs[n_variable_bins];
0022 
0023 TF1 *fitFunc, *fitFunc_fullBkg;
0024 
0025 template <typename T>
0026 string to_string_with_precision(const T a_value, const int n = 0)
0027 {
0028     ostringstream out;
0029     out.precision(n);
0030     out << fixed << a_value;
0031     return out.str();
0032 }
0033 
0034 class fitVals
0035 {
0036 public:
0037   string pTmin;
0038   string pTmax;
0039   string yield;
0040   string error;
0041   
0042   fitVals(float min, float max, float fitYield, float fitErr)
0043   {
0044     pTmin = to_string_with_precision(min, 1);
0045     pTmax = to_string_with_precision(max, 1);
0046     yield = to_string_with_precision(fitYield, 0);
0047     error = to_string_with_precision(fitErr, 0);
0048   };
0049   ~fitVals();
0050 
0051 };
0052 
0053 //Initialise histograms
0054 TH1F makeHisto(int nBins, float min, float max, string type, string xAxisTitle, string unit, int precision)
0055 {
0056   string histo_name = type;
0057   //string histo_name = type + "_" + xAxisTitle;
0058   TH1F myHisto(histo_name.c_str(), histo_name.c_str(), nBins, min, max);
0059   
0060   if (unit != "") xAxisTitle += " [" + unit +  "]";  
0061   myHisto.GetXaxis()->SetTitle(xAxisTitle.c_str());
0062 
0063   float binWidth = (float) (max - min)/nBins;
0064   string yAxisTitle = "Candidates";
0065   if (unit != "") yAxisTitle += " / " + to_string_with_precision(binWidth, precision) + " " + unit;
0066   myHisto.GetYaxis()->SetTitle(yAxisTitle.c_str());
0067   
0068   return myHisto;
0069 }
0070 
0071 Double_t fitfunc_Kshort(Double_t *x, Double_t *par)
0072 {
0073   if (x[0] > Kshort_ranges.ignore_min && x[0] < Kshort_ranges.ignore_max) 
0074   {
0075     TF1::RejectPoint();
0076     return 0;
0077   }
0078 
0079   double value = 0;
0080   for (unsigned int i = 0; i <= Kshort_polynomial_order; ++i) value += par[i]*pow(x[0], i);
0081 
0082   return value;
0083 }
0084 
0085 Double_t fitfunc_Lambda(Double_t *x, Double_t *par)
0086 {
0087   if (x[0] > Lambda_ranges.ignore_min && x[0] < Lambda_ranges.ignore_max)
0088   {
0089     TF1::RejectPoint();
0090     return 0;
0091   }
0092 
0093   double value = 0;
0094   for (unsigned int i = 0; i <= Lambda_polynomial_order; ++i) value += par[i]*pow(x[0], i);
0095 
0096   return value;
0097 }
0098 
0099 Double_t fitfunc_noGap(Double_t *x, Double_t *par)
0100 {
0101   double value = 0;
0102   for (unsigned int i = 0; i <= Kshort_polynomial_order; ++i) value += par[i]*pow(x[0], i);
0103 
0104   return value;
0105 }
0106 
0107 Double_t fitfunc_Lambda_noGap(Double_t *x, Double_t *par)
0108 {
0109   double value = 0;
0110   for (unsigned int i = 0; i <= Lambda_polynomial_order; ++i) value += par[i]*pow(x[0], i);
0111 
0112   return value;
0113 }
0114 
0115 template <typename T>
0116 void savePlots(T myPlot, string plotName, float xMin, float xMax, float yield = 0, float error = 0, float bkg = 0, float bkgErr = 0, float total = 0)
0117 {
0118   TGaxis::SetMaxDigits(3);
0119   string makeDirectory = "mkdir -p " + plotPath;
0120   system(makeDirectory.c_str());
0121 
0122   TCanvas *c1  = new TCanvas("myCanvas", "myCanvas",800,800);
0123 
0124   myPlot.GetXaxis()->SetNdivisions(505);
0125   myPlot.GetYaxis()->SetRangeUser(0, myPlot.GetMaximum()*1.6);
0126   myPlot.Sumw2();
0127   myPlot.Draw("PE1");
0128   fitFunc->Draw("SAME");
0129   fitFunc_fullBkg->Draw("SAME");
0130 
0131   TPaveText *pt;
0132   pt = new TPaveText(0.15,0.74,0.95,0.89, "NDC");
0133   pt->SetFillColor(0);
0134   pt->SetFillStyle(0);
0135   pt->SetTextFont(42);
0136   TText *pt_LaTex;
0137   pt->AddText("#it{#bf{sPHENIX}} Internal, #sqrt{s} = 200 GeV, pp");
0138   string range = to_string_with_precision(xMin, 1) + " #leq p_{T} [GeV] < " + to_string_with_precision(xMax, 1) + ", N. Cand. = " + to_string_with_precision(total, 0);
0139   string result = "Signal yield = " + to_string_with_precision(yield, 0) + " #pm " + to_string_with_precision(error, 0);
0140   string result_bkg = "Background yield = " + to_string_with_precision(bkg, 0) + " #pm " + to_string_with_precision(bkgErr, 0);
0141   pt->AddText(range.c_str());
0142   pt->AddText(result.c_str());
0143   pt->AddText(result_bkg.c_str());
0144   pt->SetBorderSize(0);
0145   pt->Draw();
0146   gPad->Modified();
0147 
0148   string extensions[] = {".C", ".pdf", ".png", ".root"};
0149   for (auto extension : extensions)
0150   {
0151     string output = plotPath + plotName + extension;
0152     c1->SaveAs(output.c_str());
0153   }
0154 }
0155 
0156 void processData(string type = "Kshort2pipi")
0157 {
0158   bool processingKshort = type == "Kshort2pipi" ? true : false;
0159 
0160   float xVals[n_variable_bins], xErrs[n_variable_bins], yVals[n_variable_bins], yErrs[n_variable_bins];
0161 
0162   string dir = "/sphenix/tg/tg01/hf/cdean/LF_analysis/data_nTuples/";
0163   string fileName = processingKshort ? dir + "output_Kshort_run3pp_looseCuts_20260608.root"
0164                                      : dir + "output_Lambda0_run3pp_looseCuts_20260608.root";
0165 
0166   TFile *file = new TFile(fileName.c_str());
0167   TTree* data = (TTree*)file->Get("DecayTree");
0168   string massBranch = processingKshort ? "K_S0_mass" : "Lambda0_mass";
0169   string pTBranch = processingKshort ? "K_S0_pT" : "Lambda0_pT";
0170   string yBranch = processingKshort ? "K_S0_rapidity" : "Lambda0_rapidity";
0171 
0172   string mass_string = processingKshort ? "m_{#pi#pi}" : "m_{p#pi}";
0173 
0174   float mass_min = processingKshort ? Kshort_ranges.min : Lambda_ranges.min;
0175   float mass_max = processingKshort ? Kshort_ranges.max : Lambda_ranges.max;
0176 
0177   for (int i = 0; i < n_variable_bins; ++i)
0178   {
0179     float min = lower_bin_bounds[i];
0180     float max = lower_bin_bounds[i+1];
0181     float signal_yield = 0;
0182     float signal_error = 0;
0183 
0184     string title = type + "_pT_range_" + to_string_with_precision(min,1) + "_to_" + to_string_with_precision(max,1);
0185     TH1F binnedMass = makeHisto(50, mass_min, mass_max, title.c_str(), mass_string.c_str(), "GeV", 3);
0186     string fillString = massBranch + " >> " + title;
0187     string cutString = to_string_with_precision(min,1) + " <= " + pTBranch + " && " + pTBranch + " < " + to_string_with_precision(max,1)
0188                      + " && " + to_string(mass_min) + " <= " + massBranch + " && " + massBranch + " <= " + to_string(mass_max)
0189                      + " && min(track_1_pT, track_2_pT) >= 0.2 && abs(" + yBranch + ") <= 0.5";
0190     data->Draw(fillString.c_str(), cutString.c_str());
0191 
0192     if (processingKshort) fitFunc = new TF1("fit", fitfunc_Kshort, mass_min, mass_max, Kshort_polynomial_order);
0193     else fitFunc = new TF1("fit", fitfunc_Lambda, mass_min, mass_max, Lambda_polynomial_order);
0194     fitFunc->SetLineColor(kRed);
0195     TFitResultPtr r = binnedMass.Fit(fitFunc, "RS");
0196 
0197     //Need to account for the region over the signal
0198     if (processingKshort) fitFunc_fullBkg = new TF1("fit", fitfunc_noGap, mass_min, mass_max, Kshort_polynomial_order);
0199     else fitFunc_fullBkg = new TF1("fit", fitfunc_Lambda_noGap, mass_min, mass_max, Lambda_polynomial_order);
0200     fitFunc_fullBkg->SetLineColor(kBlue);
0201     for (int j = 0; j < fitFunc_fullBkg->GetNpar(); ++j) fitFunc_fullBkg->SetParameter(j, fitFunc->GetParameter(j));
0202 
0203     float bkg_area = fitFunc_fullBkg->Integral(mass_min, mass_max);
0204     float bkg_areaErr = fitFunc->IntegralError(mass_min, mass_max, r->GetParams(), r->GetCovarianceMatrix().GetMatrixArray());
0205 
0206     float binWidth = binnedMass.GetBinWidth(1);
0207     float bkg_yield = bkg_area / binWidth;
0208     float bkg_yieldErr = bkg_areaErr / binWidth;
0209 
0210     signal_yield = (float) binnedMass.GetEntries() - bkg_yield;
0211     signal_error = signal_yield*(bkg_yieldErr/bkg_yield);
0212 
0213     float nEntries = (float) binnedMass.GetEntries();
0214     cout << "Number of entries in histogram = " << nEntries << endl;
0215     cout << "Background yield from total integral = " << bkg_yield << " +/- " << bkg_yieldErr << endl;
0216     cout << "Signal yield = " << signal_yield << " +/- " << signal_error << endl;
0217 
0218     savePlots(binnedMass, title.c_str(), min, max, signal_yield, signal_error, bkg_yield, bkg_yieldErr, nEntries);
0219 
0220     if (processingKshort)
0221     {
0222       Kshort_xVals[i] = xVals[i] = (max + min)/2;
0223       Kshort_xErrs[i] = xErrs[i] = (max - min)/2;
0224       Kshort_yVals[i] = yVals[i] = signal_yield;
0225       Kshort_yErrs[i] = yErrs[i] = signal_error;
0226     }
0227     else
0228     {
0229       Lambda_xVals[i] = xVals[i] = (max + min)/2;
0230       Lambda_xErrs[i] = xErrs[i] = (max - min)/2;
0231       Lambda_yVals[i] = yVals[i] = signal_yield;
0232       Lambda_yErrs[i] = yErrs[i] = signal_error;
0233     }
0234   }
0235   
0236    TCanvas *c1 = new TCanvas("c1","A Simple Graph",800,800);
0237 
0238    TGraphErrors *gr = new TGraphErrors(n_variable_bins,xVals,yVals,xErrs,yErrs);
0239    string graph_x_axis_title = processingKshort ? "K^{0}_{S} p_{T} [GeV]" : "#Lambda^{0} p_{T} [GeV]";
0240    gr->GetXaxis()->SetTitle(graph_x_axis_title.c_str());
0241    gr->GetYaxis()->SetTitle("Yield");
0242    gr->SetMarkerSize(2);
0243    gr->Draw("A*");
0244 
0245   string extensions[] = {".C", ".pdf", ".png", ".root"};
0246   for (auto extension : extensions)
0247   {
0248     string output = plotPath + type + "_yield" + extension;
0249     c1->SaveAs(output.c_str());
0250   }
0251 }
0252 
0253 void extractYields()
0254 {
0255   processData();
0256   processData("Lambda02ppi");
0257 
0258   TCanvas *c1 = new TCanvas("c1","A Simple Graph",800,800);
0259 
0260   float xVals[n_variable_bins], xErrs[n_variable_bins], yVals[n_variable_bins], yErrs[n_variable_bins];
0261 
0262   for (int i = 0; i < n_variable_bins; ++i)
0263   {
0264     xVals[i] = Kshort_xVals[i];
0265     xErrs[i] = Kshort_xErrs[i];
0266 
0267     float rawRatio = Lambda_yVals[i]/(2*Kshort_yVals[i]);
0268     float rawError = rawRatio*(TMath::Sqrt(TMath::Power(Lambda_yErrs[i]/Lambda_yVals[i], 2) + TMath::Power(Kshort_yErrs[i]/Kshort_yVals[i], 2)));
0269     yVals[i] = rawRatio;
0270     yErrs[i] = rawError;
0271 
0272     cout << "pT bin mean: " << xVals[i] 
0273      << ", Lambda yield = " << to_string_with_precision(Lambda_yVals[i], 0) << " +/- " << to_string_with_precision(Lambda_yErrs[i], 0)
0274      << ", Kshort yield = " << to_string_with_precision(Kshort_yVals[i], 0) << " +/- " << to_string_with_precision(Kshort_yErrs[i], 0) 
0275         << ", raw ratio = " << yVals[i] << " +/- " << yErrs[i] << endl;
0276   }
0277 
0278   TGraphErrors *gr = new TGraphErrors(n_variable_bins,xVals,yVals,xErrs,yErrs);
0279   gr->GetXaxis()->SetTitle("p_{T} [GeV]");
0280   gr->GetYaxis()->SetTitle("#Lambda^{0}/2K^{0}_{S} Raw Ratio");
0281   gr->GetXaxis()->SetRangeUser(0.5, 4);
0282   gr->GetYaxis()->SetRangeUser(0, 0.415);
0283   gr->SetMarkerSize(2);
0284   gr->Draw("A*");
0285 
0286   string extensions[] = {".C", ".pdf", ".png", ".root"};
0287   for (auto extension : extensions)
0288   {
0289     string output = plotPath + "RawRatio" + extension;
0290     c1->SaveAs(output.c_str());
0291   }
0292 }