File indexing completed on 2025-08-05 08:19:45
0001 #include "TFile.h"
0002 #include "TTree.h"
0003 #include "RooRealVar.h"
0004 #include "RooDataSet.h"
0005 #include "RooGaussian.h"
0006 #include "RooFitResult.h"
0007 #include "RooPlot.h"
0008 #include "TCanvas.h"
0009
0010 #include <stdio.h>
0011 #include <iostream>
0012
0013 #include <cdbobjects/CDBTTree.h>
0014
0015
0016 R__LOAD_LIBRARY(libcdbobjects.so)
0017
0018 std::vector<float> vec_peak_pos_val;
0019 std::vector<float> vec_peak_pos_err;
0020
0021 int fit_dz(const char* filename = "data.root",
0022 const char* treename = "tree",
0023 const char* branchname = "dz",
0024 TString cut = "1",
0025 TString outfile = "fit_dz.pdf",
0026 TString title = "Run 51103, fit dz",
0027 int runnumber = 51103)
0028 {
0029 TChain* chain = new TChain(treename);
0030 chain->Add(filename);
0031 int nevent = chain->GetEntries();
0032
0033 if (nevent > 0) {
0034 std::cout << "Successfully added file to the TChain." << std::endl;
0035 } else {
0036 std::cout << "Failed to add file to the TChain." << std::endl;
0037 return -1;
0038 }
0039
0040 if (chain->GetEntries(cut) < 50)
0041 {
0042 std::cout<<"Cut: "<<cut<<" , nevent used in fit = "<<chain->GetEntries(cut)<<" . Too Low!!! Fit performance maybe not be good, skipping!!!"<<std::endl;
0043 return -1;
0044 }
0045
0046 double xmin = -20;
0047 double xmax = 20;
0048 int nbins = 50;
0049 RooRealVar x(branchname, branchname, nbins, xmin, xmax);
0050 double binwidth = (xmax-xmin)/nbins;
0051
0052 TFile* newfile = new TFile("tmp.root","recreate");
0053 TTree* newtree = (TTree*) chain->CopyTree(cut);
0054
0055
0056 RooDataSet data("data", "dataset of dz", newtree, x);
0057
0058
0059 RooRealVar mean("mean", "mean of gaussian", data.mean(x), xmin, xmax);
0060 RooRealVar sigma("sigma", "width of gaussian", 0.1*data.sigma(x), 0.001, (xmax-xmin)/2);
0061
0062
0063 RooGaussian gauss("gauss", "gaussian PDF", x, mean, sigma);
0064 RooRealVar ngauss("ngauss","number of gaussian",0.2*data.sumEntries(),0,data.sumEntries());
0065
0066
0067 RooRealVar a0("a0", "constant", 0, -10, 10);
0068 RooRealVar a1("a1", "slope", 0, -1, 1);
0069 RooPolynomial poly("poly", "linear background", x, RooArgList(a1, a0));
0070 RooRealVar npoly("npoly","number of poly",0.3*data.sumEntries(),0,data.sumEntries());
0071
0072
0073 RooAddPdf model("model", "gauss + poly", RooArgList(gauss, poly), RooArgList(ngauss, npoly));
0074
0075
0076 RooFitResult* fit_result = model.fitTo(data, RooFit::Save());
0077
0078
0079 fit_result->Print();
0080
0081
0082 RooPlot* frame = x.frame();
0083 data.plotOn(frame);
0084 model.plotOn(frame);
0085 model.plotOn(frame, RooFit::Components(gauss), RooFit::LineColor(kRed), RooFit::LineStyle(kDashed));
0086 model.plotOn(frame, RooFit::Components(poly), RooFit::LineColor(kGreen), RooFit::LineStyle(kDashed));
0087
0088 frame->SetTitle(title);
0089 frame->SetXTitle("#DeltaZ [cm]");
0090 frame->SetYTitle(Form("Events / (%1.0g cm)",binwidth));
0091 frame->GetXaxis()->SetTitleSize(0.05);
0092 frame->GetYaxis()->SetTitleSize(0.05);
0093
0094 double meanValue = mean.getVal();
0095 double meanError = mean.getError();
0096 double sigmaValue = sigma.getVal();
0097 double sigmaError = sigma.getError();
0098
0099 vec_peak_pos_val.push_back(meanValue);
0100 vec_peak_pos_err.push_back(meanError);
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139 delete chain;
0140
0141 system("rm tmp.root");
0142 return 1;
0143 }
0144
0145 void CDBTTreeWrite(const std::string &fname = "test.root", float dv=0.007)
0146 {
0147 CDBTTree *cdbttree = new CDBTTree(fname);
0148 cdbttree->SetSingleFloatValue("tpc_drift_velocity",dv);
0149 cdbttree->CommitSingle();
0150 cdbttree->Print();
0151 cdbttree->WriteCDBTTree();
0152 delete cdbttree;
0153
0154 }
0155
0156 void fit(int runnumber)
0157 {
0158 gStyle->SetOptStat(0);
0159 std::vector<float> vec_trkr_z_val;
0160 std::vector<float> vec_trkr_z_err;
0161
0162
0163 vec_peak_pos_val.clear();
0164 vec_peak_pos_err.clear();
0165 vec_trkr_z_val.clear();
0166 vec_trkr_z_err.clear();
0167 float z_min = -140;
0168 float z_max = 140;
0169 float z_range = z_max - z_min;
0170 int nstep = 14;
0171 float z_stepsize = z_range / nstep;
0172 for (int i=0; i<nstep; i++)
0173 {
0174 float z_cut_min = z_min + i * z_stepsize;
0175 float z_cut_max = z_min + (i+1) * z_stepsize;
0176 int status = fit_dz(Form("Reconstructed/%d/TrackCalo_*_ana.root",runnumber), "tree", "dz", Form("fabs(dphi)<0.1 && track_z>%f && track_z<%f && fabs(dz)<20",z_cut_min,z_cut_max), Form("figure/%d/dz_fit_cuttrkrz_%d.pdf",runnumber,i), Form("Run %d, Track Z#in[%.0f,%.0f] cm",runnumber,z_cut_min,z_cut_max),runnumber);
0177 if (status==1)
0178 {
0179 vec_trkr_z_val.push_back((z_cut_min+z_cut_max)/2);
0180 vec_trkr_z_err.push_back((z_cut_max-z_cut_min)/2);
0181 }
0182 }
0183
0184 int npoint = vec_peak_pos_val.size();
0185
0186 if (npoint==0)
0187 {
0188 std::cout<<"Do not have anything to fit!!! DST is empty or Matching for this run is very bad"<<std::endl;
0189 return;
0190 }
0191
0192 int npoint_left=0;
0193 int npoint_right=0;
0194 for (int i=0; i<(vec_peak_pos_val.size()); i++)
0195 {
0196 if (vec_trkr_z_val.at(i)>0)
0197 {
0198 npoint_right++;
0199 }
0200 else if (vec_trkr_z_val.at(i)<0)
0201 {
0202 npoint_left++;
0203 }
0204 }
0205 if (npoint_left<3 || npoint_right<3)
0206 {
0207 std::cout<<"Do not have enough good point to fit!!! Matching for this run is very bad"<<std::endl;
0208 return;
0209 }
0210
0211 TCanvas *c1 = new TCanvas("c1", "Fitting Example", 800, 600);
0212 c1->SetLeftMargin(0.12);
0213 c1->SetRightMargin(0.05);
0214 TGraphErrors *graph = new TGraphErrors(vec_peak_pos_val.size(), vec_trkr_z_val.data(), vec_peak_pos_val.data(), vec_trkr_z_err.data(), vec_peak_pos_err.data());
0215 graph->SetTitle(Form("Run %d, TPC-EMCal matching;Track Z [cm];#DeltaZ=Z_{track}-Z_{calo} Peak [cm]",runnumber));
0216 graph->SetMarkerStyle(21);
0217 graph->SetMarkerColor(kBlue);
0218 graph->SetLineColor(kBlue);
0219 graph->GetYaxis()->SetRangeUser(-50,20);
0220
0221 double intercept_min = -20;
0222 double intercept_max= 20;
0223 double slope_min = -1;
0224 double slope_max = 1;
0225
0226 TF1 *fitFunc1 = new TF1("fitFunc1", "[0] + [1]*x", z_min, -10);
0227 fitFunc1->SetParameters(vec_peak_pos_val.at(npoint/2 - 2), (vec_peak_pos_val.at(npoint/2 - 2) - vec_peak_pos_val.at(0)) / (vec_trkr_z_val.at(npoint/2 - 2) - vec_trkr_z_val.at(0)));
0228 fitFunc1->SetParLimits(0, intercept_min, intercept_max);
0229 fitFunc1->SetParLimits(1, slope_min, slope_max);
0230 graph->Fit(fitFunc1, "R");
0231
0232 TF1 *fitFunc2 = new TF1("fitFunc2", "[0] + [1]*x", 10, z_max);
0233 fitFunc2->SetParameters(vec_peak_pos_val.at(npoint/2 + 1), (vec_peak_pos_val.at(npoint - 1) - vec_peak_pos_val.at(npoint/2 + 1)) / (vec_trkr_z_val.at(npoint - 1) - vec_trkr_z_val.at(npoint/2 + 1)));
0234 fitFunc2->SetParLimits(0, intercept_min, intercept_max);
0235 fitFunc2->SetParLimits(1, slope_min, slope_max);
0236 graph->Fit(fitFunc2, "R");
0237
0238 double chi2_1 = fitFunc1->GetChisquare();
0239 int ndf_1 = fitFunc1->GetNDF();
0240
0241 double chi2_2 = fitFunc2->GetChisquare();
0242 int ndf_2 = fitFunc2->GetNDF();
0243
0244 double p0_1 = fitFunc1->GetParameter(0);
0245 double p1_1 = fitFunc1->GetParameter(1);
0246 double p0_1_err = fitFunc1->GetParError(0);
0247 double p1_1_err = fitFunc1->GetParError(1);
0248 TString txt_fun1 = Form("y = %.3fx + (%.3f)",p1_1,p0_1);
0249 TString txt_quality1 = Form("#chi^2/NDF = %.2f/%d = %.2f",chi2_1,ndf_1,chi2_1/ndf_1);
0250 std::cout << "Fit left part: " << txt_fun1 << " , " << txt_quality1 << std::endl;
0251
0252 double p0_2 = fitFunc2->GetParameter(0);
0253 double p1_2 = fitFunc2->GetParameter(1);
0254 double p0_2_err = fitFunc2->GetParError(0);
0255 double p1_2_err = fitFunc2->GetParError(1);
0256 TString txt_fun2 = Form("y = %.3fx + (%.3f)",p1_2,p0_2);
0257 TString txt_quality2 = Form("#chi^2/NDF = %.2f/%d = %.2f",chi2_2,ndf_2,chi2_2/ndf_2);
0258 std::cout << "Fit right part: " << txt_fun2 << " , " << txt_quality2 << std::endl;
0259
0260 graph->Draw("AP");
0261
0262 fitFunc1->SetLineColor(kRed);
0263 fitFunc1->Draw("SAME");
0264 fitFunc2->SetLineColor(kBlue);
0265 fitFunc2->Draw("SAME");
0266
0267 double driftvelo_pre = 0.00710;
0268 double dz_separation_0_new = -(p1_1+p1_2)/2. * 2 * 105;
0269 double dz_separation_0_err = -(p1_1_err+p1_2_err)/2. * 2 * 105;
0270 double driftvelo_new = driftvelo_pre * (1+ dz_separation_0_new / 2. / 105.);
0271 double driftvelo_err = driftvelo_pre * (fabs(dz_separation_0_err) / 2. / 105.);
0272 TString printtxt1 = Form("DV used in reconstruction: %.5f cm/ns",driftvelo_pre);
0273 TString printtxt2 = Form("Calibrated DV from data: (%.5f#pm%.5f) cm/ns",driftvelo_new,driftvelo_err);
0274 cout<<printtxt1<<endl;
0275 cout<<printtxt2<<endl;
0276
0277 TPaveText *pt1 = new TPaveText(0.15, 0.275, 0.45, 0.40, "NDC");
0278 pt1->SetFillColor(0);
0279 pt1->SetTextAlign(12);
0280 pt1->AddText(txt_fun1);
0281 pt1->AddText(txt_quality1);
0282 pt1->Draw("same");
0283
0284 TPaveText *pt2 = new TPaveText(0.55, 0.275, 0.85, 0.40, "NDC");
0285 pt2->SetFillColor(0);
0286 pt2->SetTextAlign(12);
0287 pt2->AddText(txt_fun2);
0288 pt2->AddText(txt_quality2);
0289 pt2->Draw("same");
0290
0291 TPaveText *pt3 = new TPaveText(0.20, 0.15, 0.90, 0.275, "NDC");
0292 pt3->SetFillColor(0);
0293 pt3->SetTextAlign(12);
0294 pt3->AddText(printtxt1);
0295 pt3->AddText(printtxt2);
0296 pt3->Draw("same");
0297
0298 TPaveText *pt4 = new TPaveText(0.15, 0.40, 0.35, 0.50, "NDC");
0299 pt4->SetFillColor(0);
0300 pt4->SetTextAlign(12);
0301
0302
0303 double fit_quality_thr = 10;
0304 bool fit_status = true;
0305 if (chi2_1/ndf_1>fit_quality_thr || chi2_2/ndf_2>fit_quality_thr)
0306 {
0307 cout<<"ERROR: fail fit quality cut"<<endl;
0308 fit_status = false;
0309 }
0310
0311 if (fabs(p0_1-intercept_min)<1e-3 || fabs(p0_1-intercept_max)<1e-3
0312 || fabs(p1_1-slope_min)<1e-3 || fabs(p1_1-slope_max)<1e-3
0313 || fabs(p0_2-intercept_min)<1e-3 || fabs(p0_2-intercept_max)<1e-3
0314 || fabs(p1_2-slope_min)<1e-3 || fabs(p1_2-slope_max)<1e-3)
0315 {
0316 cout<<"ERROR: parameters in the limit"<<endl;
0317 fit_status = false;
0318 }
0319
0320 if ( fabs(p1_1 - p1_2) > 0.1 )
0321 {
0322 cout<<"ERROR: left fit and right fit inconsistent"<<endl;
0323 fit_status = false;
0324 }
0325
0326 double dv_ref = driftvelo_pre;
0327 if (runnumber > 50800 && runnumber < 51200)
0328 {
0329 dv_ref = 0.00625;
0330 }
0331 if (driftvelo_new/dv_ref > 1.1 || driftvelo_new/dv_ref < 0.9)
0332 {
0333 fit_status = false;
0334 }
0335
0336 if (fit_status)
0337 {
0338 pt4->SetTextColor(3);
0339 pt4->AddText("GOOD");
0340 pt4->Draw("same");
0341 c1->Update();
0342 c1->SaveAs(Form("./figure/dz_fit_trkrz_Run%d.pdf",runnumber));
0343 CDBTTreeWrite(Form("cdbttree/tpc_drift_velocity_%d.root",runnumber), (float) driftvelo_new);
0344 }
0345 else
0346 {
0347 pt4->SetTextColor(2);
0348 pt4->AddText("BAD");
0349 pt4->Draw("same");
0350 c1->Update();
0351 c1->SaveAs(Form("./figure_failed/dz_fit_trkrz_Run%d.pdf",runnumber));
0352 CDBTTreeWrite(Form("cdbttree_failed/tpc_drift_velocity_%d.root",runnumber), (float) driftvelo_new);
0353 }
0354 }