//Renata Kopecna #include #include #include #include #include #include #include #include #include #include #include #include #include #include //========================================= // // Latex in plots // //========================================= std::string latex_decay(bool DTF){ //return "K_{S}^{0}#pi^{+}#mu^{+}#mu^{-}"; if (DTF) return "K^{+}#pi^{0}#mu^{+}#mu^{-}"; else return "#K^{+}#gamma#gamma#mu^{+}#mu^{-}"; } std::string latex_Kst_decay(bool DTF){ if (DTF) return "K^{+}#pi^{0}"; else return "#K^{+}#gamma#gamma"; } std::string MeVc(){ return "MeV"; } std::string GeVc(){ return "GeV"; } std::string GeVc_2(){ return "GeV^{2}"; } std::string latex_pull(){ return "(x-x_{0})/#sigma"; } std::string latex_angle(std::string angle, bool &is_ctl, bool &is_ctk, bool &is_phi){ if(strcmp(angle.c_str(), "ctk") == 0){ is_ctk = true; return "cos(#Theta_{K})"; } else if(strcmp(angle.c_str(), "ctl") == 0){ is_ctl = true; return "cos(#Theta_{L})"; } else if(strcmp(angle.c_str(), "phi") == 0){ is_phi = true; return "#phi [rad]"; } return ""; } //Define the angles as chars, because ROOT //Very not cool, but also very not cool //of ROOT to not accept strings and I cannot be bothered const char *LATEX_Q2_CH() { return LATEX_Q2.c_str(); } const char *LATEX_TL_CH() { return LATEX_TL.c_str(); } const char *LATEX_CTL_CH(){ return LATEX_CTL.c_str();} const char *LATEX_TK_CH() { return LATEX_TK.c_str(); } const char *LATEX_CTK_CH(){ return LATEX_CTK.c_str();} const char *LATEX_PHI_CH(){ return LATEX_PHI.c_str();} std::string q2_label(double low_q2, double high_q2){ std::ostringstream qqbin; //TODO qqbin << std::fixed << std::setprecision(2) <SetOptStat(0); gStyle->SetOptFit(0); gStyle->SetLabelFont(132, "xyz"); gStyle->SetTitleFont(132, "xyz"); gStyle->SetLegendFont(132); gStyle->SetStatFont(132); gStyle->SetPaintTextFormat(".1f"); } //Save canvas with a given name and automatically append the type //Type should be specified without the dot, so eg "eps" instead of ".eps void saveTCanvas(TCanvas *c, std::string name, std::string type){ c->Print((name+"."+type).c_str(), type.c_str()); return; } //Save several file types in one go void saveTCanvas(TCanvas *c, std::string name, std::vector types){ for (auto type: types) saveTCanvas(c,name,type); return; } TLine *threeSigmaLine(double min, double max, bool plus){ int sigma = plus ? +3.0 : -3.0; TLine * line = new TLine(min, sigma, max, sigma); line->SetLineStyle(5); line->SetLineWidth(gStyle->GetLineWidth()); return line; } TLine *oneSigmaLine(double min, double max, bool plus){ int sigma = plus ? +1.0 : -1.0; TLine * line = new TLine(min, sigma, max, sigma); line->SetLineStyle(7); line->SetLineWidth(gStyle->GetLineWidth()); return line; } void plotAndSave(TH1D *hist, std::string canvasName, std::string targetPath, std::string plotType){ TCanvas* cnvs = new TCanvas(canvasName.c_str(), canvasName.c_str(), 1600, 1200); cnvs->cd(); hist->Draw(); saveTCanvas(cnvs,targetPath, plotType); delete cnvs; return; } void plotAndSave(TH2D *hist, std::string canvasName, std::string targetPath, std::string plotType){ TCanvas* cnvs = new TCanvas(canvasName.c_str(), canvasName.c_str(), 1600, 1200); cnvs->cd(); hist->Draw("COLZ"); saveTCanvas(cnvs,targetPath, plotType); delete cnvs; return; } void plotAndSaveWithLine(TH1D* hist, TF1 *line, std::string canvasName, std::string targetPath, std::string plotType){ //Create canvas TCanvas* cnvs = new TCanvas(canvasName.c_str(), canvasName.c_str(), 1600, 1200); cnvs->cd(); //Add legend //TLatex cannot do break lines and I cannot. Even. TPaveText *leg = new TPaveText(0.55,0.65,0.87,0.87); leg->Paint("NDC"); leg->SetFillColor(kWhite); leg->SetTextFont(132); //Loop over params and print them for (int n = 0; n < line->GetNpar(); n++){ std::ostringstream sParams; sParams << line->GetParName(n) << ": " << std::fixed << std::setprecision(4) << line->GetParameter(n) << "#pm" << line->GetParError(n); leg->AddText(sParams.str().c_str()); } //Draw hist->Draw("E1"); line->Draw("same"); leg->Draw("same"); //Save cnvs->Print((targetPath+"."+plotType).c_str(), plotType.c_str()); //Delete and return delete leg; delete cnvs; return; } //Sets TLatex TLatex *getPrettyTex(double TextFontSize, int TextAlign){ TLatex *tex = new TLatex(); tex->SetNDC(true); tex->SetTextFont(132); tex->SetTextSize(TextFontSize); tex->SetTextAlign(TextAlign); return tex; } //Add myThesis tag void addThesistag(double x = 0.6, double y = 0.85, int color = 1, double scaling = 1.0){ if (!PLOT_THISTHESIS_TAG) return; TLatex* lhcbtext = getPrettyTex(0.07*scaling, 13); lhcbtext->SetTextColor(color); lhcbtext->DrawLatex(x,y,THISTHESIS_TAG.c_str()); return; } //Add lhcb tag void addLHCbtag(double x = 0.6, double y = 0.85, std::string suffix = "", int color = 1, double scaling = 1.0){ TLatex* lhcbtext = getPrettyTex(0.07*scaling, 13); lhcbtext->SetTextColor(color); lhcbtext->DrawLatex(x,y,("LHCb "+suffix).c_str()); return; } //========================================= // // Angular correction plots // //========================================= //plot eff histograms for angular corrections void plotAngular(TH1D *hist, TH1D *moments, bool write,std::string name, std::string appendix, std::string q2region, TLatex *tex, std::string folderName){ TCanvas* c0 = new TCanvas("c0", "c0", 1600, 1200); c0->cd(); hist->Scale(hist->GetNbinsX()/hist->Integral()); hist->SetMinimum(0.0); hist->Draw(); hist->GetYaxis()->SetTitle("Normalized entries (a.u.)"); moments->Scale(moments->GetNbinsX()/moments->Integral()); addLHCbtag(0.15,0.27,"simulation",1,1.0); addThesistag(0.15,0.20,1,0.9); moments->Draw("samel"); if (q2region != "") tex->DrawLatex(0.85, 0.15, q2region.c_str()); if (write) saveTCanvas(c0,folderName+name+appendix,"eps"); delete c0; } //Overload the plot without plotting q2 region void plotAngular(TH1D *hist, TH1D *moments, bool write,std::string name, std::string appendix, std::string folderName){ TLatex *tex = new TLatex(); plotAngular(hist, moments, write, name, appendix, "", tex, folderName); } //plot 2D histograms for angular corrections void plotAngular(TH2D *hist, TH2D *moments, bool write, std::string name, std::string appendix, std::string q2region, TLatex *tex, std::string folderName){ TCanvas* c0 = new TCanvas("c0", "c0", 1600, 800); c0->Divide(2,1); c0->cd(1); hist->Scale(hist->GetNbinsX()*hist->GetNbinsY()/hist->Integral()); hist->SetMinimum(0.0); hist->SetMaximum(1.4); hist->Draw("colz"); c0->cd(2); moments->Scale(moments->GetNbinsX()*moments->GetNbinsY()/moments->Integral()); moments->SetMinimum(0.0); moments->SetMaximum(1.4); moments->Draw("colz"); if (q2region != "") tex->DrawLatex(0.85, 0.15, q2region.c_str()); if (write) saveTCanvas(c0,folderName+name+appendix,"eps"); delete c0; } //Overload the plot without plotting q2 region void plotAngular(TH2D *hist, TH2D *moments, bool write,std::string name, std::string appendix, std::string folderName){ TLatex *tex = new TLatex(); plotAngular(hist, moments, write, name, appendix, "", tex, folderName); } //Plot all the angular corrections in one canvas void plotAngularInOne(TCanvas *c, int whichC, TH1D *moments, TH1D *ub, TH1D *hist, TH1D* ml, bool run_minuit, double q2min, double q2max, double y, bool cross){ c->cd(whichC)->SetMargin(0.15,0.05,0.1,0.05); moments->Draw("l"); TLine* line= new TLine(); line->SetLineStyle(kDashed); if (cross){ line->SetLineColor(kGray+1); line->DrawLine(q2min, -0.5, q2max, +0.5); line->DrawLine(q2min, +0.5, q2max, -0.5); } else{ ub->Draw("same"); hist->Draw("same"); if (run_minuit) ml->Draw("lsame"); line->SetLineColor(kRed); line->DrawLine(q2min, y, q2max, y); } } //Label axes for angular correction polynomial scan void labelAngularScan(std::vectorscan_low, std::vectorscan_range,TH2D *hist){ //label the x-axis //loop over the range in thetak and thetal and print all possible combination for(int tk = 0; tk < scan_range.at(1); tk++){ for(int tl = 0; tl < scan_range.at(2); tl++){ hist->GetXaxis()->SetBinLabel(tk * scan_range.at(2) + tl + 1, //+1 because bins start at 1 ("#bf{"+std::to_string(tk+scan_low.at(1))+"} - "+std::to_string(tl+scan_low.at(2))).c_str()); } } //label the y-axis for(int qq = 0; qq < scan_range.at(0); qq++){ for(int fi =0; fi < scan_range.at(3); fi++){ hist->GetYaxis()->SetBinLabel(qq * scan_range.at(3) + fi + 1, ("#bf{"+std::to_string(qq+scan_low.at(0))+"} - "+std::to_string(fi+scan_low.at(3))).c_str()); } } //draw labels on x-axis vertically hist->GetXaxis()->LabelsOption("v"); return; } //========================================= // // Fit results plots // //========================================= int design_pull_basic(TH1D *pull, Float_t textsize, double eff_pullHeight){ pull->GetXaxis()->SetNoExponent(); //<-- spoils MaxDigits settings, so don't use it on other axis pull->GetXaxis()->SetNdivisions(gStyle->GetNdivisions("X")); pull->GetYaxis()->SetTitleSize(textsize/eff_pullHeight); pull->GetYaxis()->SetLabelSize(textsize/eff_pullHeight); pull->GetYaxis()->SetTitleOffset(gStyle->GetTitleOffset()*eff_pullHeight); return 0; } int design_pull(TH1D *pull, Color_t lineColor, Color_t fillColor, double eff_pullHeight, double pullFrameRange){ Float_t textsize = gStyle->GetTextSize(); pull->GetXaxis()->SetTitleOffset(1.05); design_pull_basic(pull, textsize, eff_pullHeight); pull->GetXaxis()->SetTitleSize (textsize/eff_pullHeight); pull->GetXaxis()->SetLabelSize (textsize/eff_pullHeight); pull->GetXaxis()->SetTickLength (pull->GetXaxis()->GetTickLength()/(eff_pullHeight/(1-eff_pullHeight))); pull->GetYaxis()->CenterTitle(); pull->GetYaxis()->SetNdivisions (3, 9, 0, kTRUE);//gStyle->GetNdivisions("Y")); pull->GetYaxis()->SetRangeUser (-pullFrameRange, pullFrameRange); pull->SetFillColor(fillColor); pull->SetLineColor(lineColor); pull->SetLineWidth(1); return 0; } int design_pull(TGraphErrors *pull, Color_t lineColor, Color_t fillColor, double eff_pullHeight, double pullFrameRange){ Float_t textsize = gStyle->GetTextSize(); pull->GetXaxis()->SetTitleOffset(1.05); pull->GetXaxis()->SetNoExponent(); //<-- spoils MaxDigits settings, so don't use it on other axis pull->GetYaxis()->SetTitleSize(textsize/eff_pullHeight); pull->GetYaxis()->SetLabelSize(textsize/eff_pullHeight); pull->GetYaxis()->SetTitleOffset(gStyle->GetTitleOffset()*eff_pullHeight); pull->GetXaxis()->SetTitleSize (textsize/eff_pullHeight); pull->GetXaxis()->SetLabelSize (textsize/eff_pullHeight); pull->GetXaxis()->SetTickLength (pull->GetXaxis()->GetTickLength()/(eff_pullHeight/(1-eff_pullHeight))); pull->GetYaxis()->CenterTitle(); pull->GetYaxis()->SetRangeUser (-pullFrameRange, pullFrameRange); pull->SetFillColor(fillColor); pull->SetLineColor(lineColor); pull->SetLineWidth(1); return 0; } void drawResonances(TCanvas *c, double min, double max){ c->cd(); TBox* box = new TBox(); box->SetFillColor(21); box->SetLineColor(21); box->SetFillStyle(1001); box->DrawBox(0.98, min, 1.10, max); box->DrawBox(8.0, min, 11.0, max); box->DrawBox(12.5, min, 15.0, max); c->Update(); //Probably not needed, but just ot be sure return; } void drawResonances(TPad *c, double min, double max){ c->cd(); TBox* box = new TBox(); box->SetFillColor(21); box->SetLineColor(21); box->SetFillStyle(1001); box->DrawBox(0.98, min, 1.10, max); box->DrawBox(8.0, min, 11.0, max); box->DrawBox(12.5, min, 15.0, max); c->Update(); //Probably not needed, but just ot be sure return; } void designTGraph(TGraphErrors *graph, std::string title, std::string xAxisName, std::string yAxisName, Color_t color, Int_t markerStyle){ graph->SetName(title.c_str()); graph->SetLineColor(color); //graph->SetLineWidth(0); graph->SetMarkerStyle(markerStyle); graph->SetMarkerColor(color); graph->GetXaxis()->SetTitle(xAxisName.c_str()); graph->GetYaxis()->SetTitle(yAxisName.c_str()); graph->GetXaxis()->SetTitleOffset(1.0); graph->GetYaxis()->SetTitleOffset(1.7); graph->SetTitle(""); graph->GetXaxis()->SetLabelSize(0.09); graph->GetYaxis()->SetLabelSize(0.09); graph->GetXaxis()->SetTitleSize(0.07); graph->GetYaxis()->SetTitleSize(0.05); return; } void designMultiGraph(TMultiGraph *multGraph, std::string title, std::string xAxisName, std::string yAxisName){ //One needs to draw the multGraph first! multGraph->SetName(title.c_str()); multGraph->GetXaxis()->SetTitle(xAxisName.c_str()); multGraph->GetYaxis()->SetTitle(yAxisName.c_str()); gStyle->SetOptStat(0); multGraph->GetXaxis()->SetTitleOffset(1.0); multGraph->GetYaxis()->SetTitleOffset(1.4); multGraph->SetTitle(""); multGraph->GetXaxis()->SetLabelSize(0.05); multGraph->GetYaxis()->SetLabelSize(0.05); multGraph->GetXaxis()->SetTitleSize(0.05); multGraph->GetYaxis()->SetTitleSize(0.055); return; } int design_YieldInQ2(int Run, TGraphErrors *graphSig, TGraphErrors *graphBkg, TGraphErrors *graphSignificance, TGraphErrors *CMS, bool fixRange, std::string savePath, std::vector extensions){ std::string mainName = "Q2_Run" + std::to_string(Run); double y_scale = 1.5; double y_scale_1 = (Run==1) ? 2.5 : 1.75; //Create a TCanvas TCanvas *c = new TCanvas(mainName.c_str(),mainName.c_str(),750, 575); c->SetRightMargin(0.13); c->SetLeftMargin(0.23); c->SetTopMargin(0.075); c->SetBottomMargin(0.12); c->cd(); designTGraph(graphSig,"Signal","Q2","Yield",kBlack,20); designTGraph(graphBkg,"Background","Q2","Yield",kRed,20); graphSig->SetLineStyle(1); graphSig->SetLineWidth(1); graphSig->SetMarkerSize(0.5); graphBkg->SetLineStyle(1); graphBkg->SetLineWidth(1); graphBkg->SetMarkerSize(0.65); designTGraph(graphSignificance,"Significance","Q2","S/(S+B)",kBlue,20); designTGraph(CMS,"Significance_CMS","Q2","S/(S+B)",kGreen+2,20); graphSignificance->GetYaxis()->SetRangeUser(0.0,graphSignificance->GetY()[0]*y_scale); graphSignificance->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE); CMS->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE); graphSignificance->SetLineWidth(3); CMS->SetLineWidth(3); //Create multigraphs TMultiGraph *mg = new TMultiGraph(); mg->Add(graphSig,"AP"); mg->Add(graphBkg,"AP"); mg->Draw("AP"); mg->GetYaxis()->SetRangeUser(0.0,graphBkg->GetY()[1]*y_scale); mg->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE); designMultiGraph(mg,"","q^{2} [GeV^{2}]","Yield"); TMultiGraph *mg_FoM = new TMultiGraph(); mg_FoM->Add(graphSignificance,"AP"); mg_FoM->Add(CMS,"AP"); mg_FoM->Draw("AP"); mg_FoM->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE); designMultiGraph(mg_FoM,"","q^{2} [GeV^{2}]","S/(S+B)"); //Create two pads (to get significance y-axis on the right) TPad *pad1 = new TPad("pad1","",0,0,1,1); TPad *pad2 = new TPad("pad2","",0,0,1,1); pad2->SetFillStyle(4000); //will be transparent pad2->SetFrameFillStyle(0); pad1->SetRightMargin(0.13); pad1->SetLeftMargin(0.15); pad1->SetTopMargin(0.07); pad1->SetBottomMargin(0.12); pad2->SetRightMargin(0.13); pad2->SetLeftMargin(0.15); pad2->SetTopMargin(0.07); pad2->SetBottomMargin(0.12); pad1->Draw(); pad1->cd(); //Add legends TLegend *leg = new TLegend(0.15,0.93,0.52,0.82); leg->AddEntry(graphSig, "Signal yield","l"); leg->AddEntry(graphBkg, "Background yield","l"); TLegend *legSignificance = new TLegend(0.52,0.93,0.8,0.82); legSignificance->AddEntry(graphSignificance, "Significance","l"); legSignificance->AddEntry(CMS, "CMS","l"); //Plot it pad1->cd(); gStyle->SetGridColor(kGray); pad1->SetGridy(); pad1->SetGridx(); mg->Draw("SAME"); mg->GetYaxis()->SetTitle("Yield"); mg->GetYaxis()->SetRangeUser(0.0,graphBkg->GetY()[1]*y_scale); mg->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE); mg->GetXaxis()->SetLabelSize(0); mg->GetYaxis()->SetTickLength(0); leg->Draw("SAME"); pad1->Update(); c->cd(); pad2->Draw(); pad2->cd(); //Get axis on the left side TGaxis *axis = new TGaxis(Q2_MAX_RANGE,0.0,Q2_MAX_RANGE,graphSignificance->GetY()[0]*y_scale_1,0,graphSignificance->GetY()[0]*y_scale_1,510,"+L"); axis->SetTitle("S/sqrt(S+B)"); axis->SetTextFont(21); mg_FoM->Draw("AP"); mg_FoM->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE); mg_FoM->GetYaxis()->SetRangeUser(0.0,graphSignificance->GetY()[0]*y_scale_1); mg_FoM->GetYaxis()->SetLabelSize(0); mg_FoM->GetYaxis()->SetTickLength(0); mg_FoM->GetYaxis()->SetTitle(""); axis->Draw("SAME"); legSignificance->Draw("SAME"); pad2->Update(); c->cd(); //Save it if (!fixRange) savePath = savePath + "_sigma"; TFile *file = new TFile ((savePath+".root").c_str(), "RECREATE"); file->cd(); graphSig->Write(); graphBkg->Write(); graphSignificance->Write(); CMS->Write(); c->Write(); file->Close(); saveTCanvas(c,savePath,extensions); return 0; } int design_SignificanceInQ2(int Run, TGraphErrors *graphSignificance, TGraphErrors *CMS, bool fixRange, std::string savePath, std::vectorextensions){ std::string mainName = "Q2_Run" + std::to_string(Run); double y_scale = 1.4; //Create a TCanvas TCanvas *c = new TCanvas(mainName.c_str(),mainName.c_str(),750, 600); c->SetRightMargin(0.13); c->SetLeftMargin(0.15); c->SetTopMargin(0.07); c->SetBottomMargin(0.12); gStyle->SetGridColor(kGray); c->SetGridy(); c->SetGridx(); c->SetBottomMargin(0.16); designTGraph(graphSignificance,"Significance","Q2","S/(S+B)",kBlue,20); designTGraph(CMS,"Significance_CMS","Q2","S/(S+B)",kGreen+2,20); graphSignificance->GetYaxis()->SetRangeUser(0.0,graphSignificance->GetY()[0]*y_scale); graphSignificance->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE); CMS->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE); graphSignificance->SetLineWidth(3); CMS->SetLineWidth(3); //Create multigraph TMultiGraph *mg_FoM = new TMultiGraph(); mg_FoM->Add(graphSignificance,"AP"); mg_FoM->Add(CMS,"AP"); mg_FoM->Draw("AP"); designMultiGraph(mg_FoM,"","q^{2} [GeV^{2}]","S/(S+B)"); //Add legend TLegend *legSignificance = new TLegend(0.35,0.9,0.65,0.75); legSignificance->AddEntry(graphSignificance, "Significance","l"); legSignificance->AddEntry(CMS, "CMS","l"); //Plot it c->cd(); mg_FoM->Draw("AP"); mg_FoM->GetYaxis()->SetTitle("S/(S+B)"); mg_FoM->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE); mg_FoM->GetYaxis()->SetRangeUser(0.0,graphSignificance->GetY()[0]*y_scale); mg_FoM->GetXaxis()->SetTitle("q^{2} [GeV^{2}]"); legSignificance->Draw("SAME"); c->Update(); //Save it if (!fixRange) savePath = savePath + "_sigma"; TFile *file = new TFile ((savePath+".root").c_str(), "RECREATE"); file->cd(); graphSignificance->Write(); CMS->Write(); c->Write(); file->Close(); saveTCanvas(c,savePath,extensions); return 0; }