|
| 1 | +/// \file |
| 2 | +/// \ingroup tutorial_math |
| 3 | +/// \notebook |
| 4 | +/// Tutorial illustrating how to create a plot comparing a Breit Wigner to a Relativistic Breit Wigner |
| 5 | +/// |
| 6 | +/// can be run with: |
| 7 | +/// |
| 8 | +/// ~~~{.cpp} |
| 9 | +/// root[0] .x BreitWigner.C |
| 10 | +/// ~~~ |
| 11 | +/// |
| 12 | +/// \macro_image |
| 13 | +/// \macro_code |
| 14 | +/// |
| 15 | +/// \author Jack Lindon |
| 16 | + |
| 17 | +#include "TMath.h" |
| 18 | + |
| 19 | +#include <limits> |
| 20 | +#include <string> |
| 21 | +#include "TAxis.h" |
| 22 | +#include "TGraph.h" |
| 23 | +#include "TCanvas.h" |
| 24 | +#include "TLatex.h" |
| 25 | +#include "TLegend.h" |
| 26 | +#include "TStyle.h" //For gStyle to remove stat box. |
| 27 | + |
| 28 | + |
| 29 | +void plotTwoTGraphs(Double_t x[], Double_t y1[], Double_t y2[], const Int_t nPoints |
| 30 | + , Double_t lowerXLimit, Double_t upperXLimit |
| 31 | + , Double_t lowerYLimit, Double_t upperYLimit |
| 32 | + , std::string legend1, std::string legend2 |
| 33 | + , std::string plotTitle1, std::string plotTitle2, std::string plotTitle3 |
| 34 | + , std::string pdfTitle){ |
| 35 | + |
| 36 | + /////////////////////////////////////////////////////// |
| 37 | + //Define variables for plot aesthetics and positioning |
| 38 | + Double_t legendXPos = 0.63; Double_t legendYPos = 0.85; |
| 39 | + Double_t legendXWidth = 0.29; Double_t legendYHeight = 0.1; |
| 40 | + Double_t plotTitleXPos = 0.23; Double_t plotTitleYPos = 0.25; |
| 41 | + Double_t fontSize = 0.04; |
| 42 | + Double_t lineWidth = 2; |
| 43 | + bool setLimitPlotLogScale = true; |
| 44 | + std::string xAxisTitle = "E [GeV]"; std::string yAxisTitle = "Events"; |
| 45 | + Double_t xAxisTitleOffset = 1; Double_t yAxisTitleOffset = 1.3; |
| 46 | + gStyle->SetOptStat(0); |
| 47 | + |
| 48 | + /////////////////////////////////////////////////////// |
| 49 | + // Initialize TGraphs |
| 50 | + TGraph* gr1 = new TGraph(nPoints,x,y1); |
| 51 | + TGraph* gr2 = new TGraph(nPoints,x,y2); |
| 52 | + gr1->SetLineWidth(lineWidth); |
| 53 | + gr2->SetLineWidth(lineWidth); |
| 54 | + gr1->SetLineColor(kBlack); |
| 55 | + gr2->SetLineColor(kBlue); |
| 56 | + |
| 57 | + ///////////////////////////////////////////////////////// |
| 58 | + // Initialize canvas |
| 59 | + TCanvas* c1 = new TCanvas("c1","transparent pad",200,10,600,600); |
| 60 | + c1->SetLogy(setLimitPlotLogScale); |
| 61 | + c1->SetTicks(1,1); |
| 62 | + c1->SetRightMargin(0.02); |
| 63 | + c1->SetTopMargin(0.02); |
| 64 | + |
| 65 | + |
| 66 | + /////////////////////////////////////////////////////// |
| 67 | + //Make just a basic invisible TGraph just for the axes |
| 68 | + const Double_t axis_x[2] = {lowerXLimit,upperXLimit}; |
| 69 | + const Double_t axis_y[2] = {lowerYLimit,upperYLimit}; |
| 70 | + TGraph* grAxis = new TGraph(2, axis_x, axis_y); |
| 71 | + grAxis->SetTitle(""); |
| 72 | + grAxis->GetYaxis()->SetTitle(yAxisTitle.c_str()); |
| 73 | + grAxis->GetXaxis()->SetTitle(xAxisTitle.c_str()); |
| 74 | + grAxis->GetXaxis()->SetRangeUser(lowerXLimit,upperXLimit); |
| 75 | + grAxis->GetYaxis()->SetRangeUser(lowerYLimit,upperYLimit); |
| 76 | + grAxis->GetXaxis()->SetLabelSize(fontSize); |
| 77 | + grAxis->GetYaxis()->SetLabelSize(fontSize); |
| 78 | + grAxis->GetXaxis()->SetTitleSize(fontSize); |
| 79 | + grAxis->GetYaxis()->SetTitleSize(fontSize); |
| 80 | + grAxis->GetXaxis()->SetTitleOffset(xAxisTitleOffset); |
| 81 | + grAxis->GetYaxis()->SetTitleOffset(yAxisTitleOffset); |
| 82 | + grAxis->SetLineWidth(0);//So invisible |
| 83 | + |
| 84 | + /////////////////////////////////////////////////////////// |
| 85 | + // Make legend and set aesthetics |
| 86 | + auto legend = new TLegend(legendXPos,legendYPos,legendXPos+legendXWidth,legendYPos+legendYHeight); |
| 87 | + legend->SetFillStyle(0); |
| 88 | + legend->SetBorderSize(0); |
| 89 | + legend->SetTextSize(fontSize); |
| 90 | + legend->AddEntry(gr1,legend1.c_str(),"L"); |
| 91 | + legend->AddEntry(gr2,legend2.c_str(),"L"); |
| 92 | + |
| 93 | + |
| 94 | + ///////////////////////////////////////////////////////////// |
| 95 | + // Add plot title to plot. Make in three lines so not crowded. |
| 96 | + // Shift each line down by shiftY |
| 97 | + float shiftY{0.037}; |
| 98 | + TLatex* tex_Title = new TLatex(plotTitleXPos,plotTitleYPos-0*shiftY,plotTitle1.c_str()); |
| 99 | + tex_Title->SetNDC(); |
| 100 | + tex_Title->SetTextFont(42); |
| 101 | + tex_Title->SetTextSize(fontSize); |
| 102 | + tex_Title->SetLineWidth(lineWidth); |
| 103 | + TLatex* tex_Title2 = new TLatex(plotTitleXPos,plotTitleYPos-1*shiftY,plotTitle2.c_str()); |
| 104 | + tex_Title2->SetNDC(); |
| 105 | + tex_Title2->SetTextFont(42); |
| 106 | + tex_Title2->SetTextSize(fontSize); |
| 107 | + tex_Title2->SetLineWidth(lineWidth); |
| 108 | + TLatex* tex_Title3 = new TLatex(plotTitleXPos,plotTitleYPos-2*shiftY,plotTitle3.c_str()); |
| 109 | + tex_Title3->SetNDC(); |
| 110 | + tex_Title3->SetTextFont(42); |
| 111 | + tex_Title3->SetTextSize(fontSize); |
| 112 | + tex_Title3->SetLineWidth(lineWidth); |
| 113 | + |
| 114 | + |
| 115 | + ///////////////////////////////////// |
| 116 | + // Draw everything |
| 117 | + grAxis->Draw("AL"); |
| 118 | + gr1->Draw("L same"); |
| 119 | + gr2->Draw("L same"); |
| 120 | + legend->Draw(); |
| 121 | + tex_Title->Draw(); |
| 122 | + tex_Title2->Draw(); |
| 123 | + tex_Title3->Draw(); |
| 124 | + c1->RedrawAxis(); //Be sure to redraw axis AFTER plotting TGraphs otherwise TGraphs will be on top of tick marks and axis borders. |
| 125 | + |
| 126 | + gPad->Print(pdfTitle.c_str()); |
| 127 | + |
| 128 | +} |
| 129 | + |
| 130 | + |
| 131 | +void BreitWigner(){ |
| 132 | + |
| 133 | + ///////////////////////////////////////////////////////// |
| 134 | + // Define x axis limits and steps for each plotted point |
| 135 | + const Int_t nPoints = 1000; |
| 136 | + Double_t xMinimum = 0; Double_t xMaximum = 13000; |
| 137 | + Double_t xStepSize = (xMaximum-xMinimum)/nPoints; |
| 138 | + |
| 139 | + /////////////////////////////////////////////////////// |
| 140 | + // Define arrays of (x,y) points. |
| 141 | + Double_t x[nPoints]; |
| 142 | + Double_t y_nonRelBW[nPoints], y_relBW[nPoints]; |
| 143 | + |
| 144 | + |
| 145 | + ////////////////////////////////// |
| 146 | + // Define Breit-Wigner parameters |
| 147 | + Double_t width = 1350; |
| 148 | + Double_t sigma = 269.7899; |
| 149 | + Double_t median = 9000; |
| 150 | + |
| 151 | + /////////////////////////////////////////////////// |
| 152 | + // Loop over x axis range, filling in (x,y) points, |
| 153 | + // and finding y minimums and maximums for axis limit. |
| 154 | + Double_t yMinimum = std::numeric_limits<Double_t>::max(); |
| 155 | + Double_t yMaximum = TMath::BreitWignerRelativistic(median,median,width); //y maximum is at x=median (and non relativistic = relativistic at median so choice of function does not matter). |
| 156 | + for (Int_t i=0;i<nPoints;i++) { |
| 157 | + Double_t currentX = xMinimum+i*xStepSize; |
| 158 | + x[i] = currentX; |
| 159 | + y_nonRelBW[i] = TMath::BreitWigner(currentX,median,width); |
| 160 | + y_relBW[i] = TMath::BreitWignerRelativistic(currentX,median,width); |
| 161 | + |
| 162 | + if (y_nonRelBW[i]<yMinimum){yMinimum = y_nonRelBW[i];} |
| 163 | + if (y_relBW[i]<yMinimum){yMinimum = y_relBW[i];} |
| 164 | + } |
| 165 | + |
| 166 | + plotTwoTGraphs(x, y_nonRelBW, y_relBW, nPoints |
| 167 | + , xMinimum, xMaximum //xAxis limits |
| 168 | + , yMinimum/4, yMaximum*4 //yAxis limits, expand for aesthetics. |
| 169 | + ,"NonRel BW", "Rel BW" //Legend entries |
| 170 | + , "Comparing BW", "M = " + std::to_string(int(round(median))) + " GeV", "#Gamma = " + std::to_string(int(round(width))) + " GeV" //Plot Title entry (three lines) |
| 171 | + , "BW_M"+std::to_string(int(round(median)))+"_Gamma" + std::to_string(int(round(width))) +".pdf)" //PDF file title. |
| 172 | + ); |
| 173 | +} |
0 commit comments