diff --git a/.github/workflows/resultchecks.yml b/.github/workflows/resultchecks.yml new file mode 100644 index 0000000..24cd71f --- /dev/null +++ b/.github/workflows/resultchecks.yml @@ -0,0 +1,54 @@ +name: Result_checks +on: + workflow_run: + workflows: [Software_check] + types: [completed] + +jobs: + compare_plots: + runs-on: ubuntu-latest + container: + image: cmscloud/al9-cms:latest + options: --user root + steps: + - name: Checking_out_code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Preparing_packages + run: | + echo "python version="`python3 -V` + ls -la + pwd + dnf install -y root ImageMagick python3-root + echo "ROOT version="`root-config --version` + - name: Python_plots + run: | + source scripts/setup_cmstyle + cd tests + for xfch in test_cmsCanvas test_THStack test_cms2DHisto + do + python3 ${xfch}.py + sha256sum ${xfch}.png + done + - name: Cpp_plots + run: | + source scripts/setup_cmstyle + cd tests + for xfch in test_cmsCanvas test_THStack test_cms2DHisto + do + root -b -q ${xfch}.C + sha256sum ${xfch}_C.png + done + - name: Comparison_of_plots + run: | + cd tests + for xfch in `ls *_C.png` + do + xfch2=`echo ${xfch} | sed s%_C.png%.png%` + echo -n "Comparison of $xfch and $xfch2 yields " + # NCC metric seems to have problems in some recent versions??? + # echo `compare -metric NCC $xfch $xfch2 /dev/null` + echo `compare -metric RMSE $xfch $xfch2 /dev/null` + done +# diff --git a/.github/workflows/softwarecheck.yml b/.github/workflows/softwarecheck.yml index 4fa8241..fe93b5c 100644 --- a/.github/workflows/softwarecheck.yml +++ b/.github/workflows/softwarecheck.yml @@ -16,8 +16,8 @@ jobs: fetch-depth: 0 - name: Checking_python_3.9 run: | - python3 -V - ls + echo "python version="`python3 -V` + ls -la pwd python3 -m py_compile src/cmsstyle/cmsstyle.py ls -lh src/cmsstyle/__pycache__/ @@ -27,7 +27,7 @@ jobs: echo '{gROOT->LoadMacro("cmsstyle.C++");}' > compiling.C dnf install -y root - echo 'ROOT VERSION='`root-config --version` + echo "ROOT version="`root-config --version` root -q compiling.C ls -lh cmsstyle_C.so # @@ -35,10 +35,10 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout repository (on host) + - name: Checkout repository (on host) for python 2.7 check uses: actions/checkout@v4 - - name: Run checks inside container + - name: Run checks inside container for python 2.7 check uses: addnab/docker-run-action@v3 with: image: cmscloud/cc7-cms:latest @@ -47,4 +47,5 @@ jobs: python -V find . -type f python -m py_compile src/cmsstyle/cmsstyle.py - ls -lh src/cmsstyle/cmsstyle.pyc \ No newline at end of file + ls -lh src/cmsstyle/cmsstyle.pyc +# diff --git a/src/cmsstyle.C b/src/cmsstyle.C index e77c4a3..d01d408 100644 --- a/src/cmsstyle.C +++ b/src/cmsstyle.C @@ -173,7 +173,7 @@ void ResetCmsDescriptors (void) } // ---------------------------------------------------------------------- -void SetEnergy (float energy, const std::string &unit) +void SetEnergy (Double_t energy, const std::string &unit) // This methos sets the centre-of-mass energy value and unit to be displayed. { if (energy==0) cms_energy=unit; @@ -189,7 +189,7 @@ void SetEnergy (float energy, const std::string &unit) } // ---------------------------------------------------------------------- -void SetLumi (Float_t lumi, const std::string &unit, const std::string &run, int round_lumi) +void SetLumi (Double_t lumi, const std::string &unit, const std::string &run, int round_lumi) // This method sets the CMS-luminosity related information for the plot. { cms_lumi = ""; @@ -213,7 +213,7 @@ void SetLumi (Float_t lumi, const std::string &unit, const std::string &run, int } // ---------------------------------------------------------------------- -void SetCmsText (const std::string &text, const Font_t &font, float size) +void SetCmsText (const std::string &text, const Font_t &font, Double_t size) // This method allows to set the CMS text. as needed. { cmsText=text; @@ -285,21 +285,21 @@ void SetExtraText (const std::string &text, const Font_t &font) // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- -Float_t cmsReturnMaxY (const std::vector objs) +Double_t cmsReturnMaxY (const std::vector objs) // Returns the maximum value associated to the objects that are going to be // plotted. { - Float_t maxval=0; + Double_t maxval=0; for (auto xobj : objs) { if (xobj->InheritsFrom(TH1::Class())) { // An Histogram - Float_t value = ((TH1*) xobj)->GetBinContent(((TH1*) xobj)->GetMaximumBin()); + Double_t value = ((TH1*) xobj)->GetBinContent(((TH1*) xobj)->GetMaximumBin()); value += ((TH1*) xobj)->GetBinError(((TH1*) xobj)->GetMaximumBin()); if (maxvalInheritsFrom(THStack::Class())) { // A THStack! - Float_t value = ((THStack*) xobj)->GetMaximum(); + Double_t value = ((THStack*) xobj)->GetMaximum(); if (maxval objs) while (i>0) { i -= 1; - Float_t ivalue = y[i]; + Double_t ivalue = y[i]; ivalue += std::max(ey[i],((TGraph *) xobj)->GetErrorYhigh(i)); if (maxval objs) // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- TCmsCanvas *cmsCanvas (const char *canvName, - Float_t x_min, - Float_t x_max, - Float_t y_min, - Float_t y_max, + Double_t x_min, + Double_t x_max, + Double_t y_min, + Double_t y_max, const char *nameXaxis, const char *nameYaxis, Bool_t square, Int_t iPos, - Float_t extraSpace, + Double_t extraSpace, Bool_t with_z_axis, - Float_t scaleLumi, - Float_t yTitOffset) + Double_t scaleLumi, + Double_t yTitOffset) // This method defines and returns the TCmsCanvas (a wrapper for TCanvas) for // a normal/basic plot. { @@ -351,13 +351,24 @@ TCmsCanvas *cmsCanvas (const char *canvName, // Set canvas dimensions and margins Int_t H = 600; - Float_t W = 800; + Double_t W = 800; if (square) W = 600; - Float_t T = 0.07 * H; - Float_t B = 0.125 * H; // Changing this to allow more space in X-title (i.e. subscripts) - Float_t L = 0.14 * H; // Changing these to leave more space - Float_t R = 0.04 * H; + Double_t T = 0.07 * H; + Double_t B = 0.125 * H; // Changing this to allow more space in X-title (i.e. subscripts) + Double_t L = 0.145 * H; // Changing this to leave more space + Double_t R = 0.05 * H; // Changing this to leave more space + + // The position of the y-axis title may also change a bit the plot: + Double_t y_offset = 0.78; + if (yTitOffset<-998) { + y_offset = 0.78; + if (square) y_offset = 1.2; // Changed to fitting larger font + } + else y_offset = yTitOffset; + + if (y_offset<1.5) L += y_offset*50-60; // Some adjustment + else if (y_offset<1.8) L += (y_offset-1.4)*35+25; // Setting up the TCanvas TCmsCanvas *canv = new TCmsCanvas(canvName, canvName, 50, 50, W, H); @@ -376,13 +387,6 @@ TCmsCanvas *cmsCanvas (const char *canvName, // Draw the frame for plotting things and set axis labels TH1 *h = canv->DrawFrame(x_min, y_min, x_max, y_max); - Float_t y_offset = 0.78; - if (yTitOffset<-998) { - y_offset = 0.78; - if (square) y_offset = 1.15; // Changed to fitting larger font - } - else y_offset = yTitOffset; - h->GetYaxis()->SetTitleOffset(y_offset); h->GetXaxis()->SetTitleOffset(1.05); // Changed to fitting larger font h->GetXaxis()->SetTitle(nameXaxis); @@ -399,7 +403,7 @@ TCmsCanvas *cmsCanvas (const char *canvName, } // ---------------------------------------------------------------------- -void CMS_lumi (TPad *ppad, Int_t iPosX, Float_t scaleLumi) +void CMS_lumi (TPad *ppad, Int_t iPosX, Double_t scaleLumi) // This is the method to draw the "CMS" seal (logo and text) and put the // luminosity value. { @@ -407,22 +411,22 @@ void CMS_lumi (TPad *ppad, Int_t iPosX, Float_t scaleLumi) /// implementation was complicated and obscure, so rewritten here with a /// cleaner coding. - Float_t relPosX = 0.035; - Float_t relPosY = 0.035; - Float_t relExtraDY = 1.2; + Double_t relPosX = 0.035; + Double_t relPosY = 0.035; + Double_t relExtraDY = 1.2; Bool_t outOfFrame = (int(iPosX / 10) == 0); Int_t alignX_ = max(int(iPosX / 10), 1); Int_t alignY_ = (iPosX==0)?1:3; Int_t align_ = 10 * alignX_ + alignY_; - Float_t H = ppad->GetWh() * ppad->GetHNDC(); - Float_t W = ppad->GetWw() * ppad->GetWNDC(); - Float_t l = ppad->GetLeftMargin(); - Float_t t = ppad->GetTopMargin(); - Float_t r = ppad->GetRightMargin(); - Float_t b = ppad->GetBottomMargin(); - Float_t outOfFrame_posY = 1 - t + lumiTextOffset * t; + Double_t H = ppad->GetWh() * ppad->GetHNDC(); + Double_t W = ppad->GetWw() * ppad->GetWNDC(); + Double_t l = ppad->GetLeftMargin(); + Double_t t = ppad->GetTopMargin(); + Double_t r = ppad->GetRightMargin(); + Double_t b = ppad->GetBottomMargin(); + Double_t outOfFrame_posY = 1 - t + lumiTextOffset * t; ppad->cd(); @@ -435,12 +439,12 @@ void CMS_lumi (TPad *ppad, Int_t iPosX, Float_t scaleLumi) // Now we go to the CMS message: - Float_t posX_ = 0; + Double_t posX_ = 0; if (iPosX % 10 <= 1) posX_ = l + relPosX * (1 - l - r); else if (iPosX % 10 == 2) posX_ = l + 0.5 * (1 - l - r); else if (iPosX % 10 == 3) posX_ = 1 - r - relPosX * (1 - l - r); - Float_t posY_ = 1 - t - relPosY * (1 - t - b); + Double_t posY_ = 1 - t - relPosY * (1 - t - b); if (outOfFrame) { // CMS logo and extra text out of the frame if (useCmsLogo.length()>0) { // Using CMS Logo instead of the text label (uncommon!) @@ -450,8 +454,8 @@ void CMS_lumi (TPad *ppad, Int_t iPosX, Float_t scaleLumi) if (cmsText.length()!=0) { drawText(cmsText.c_str(),l,outOfFrame_posY,cmsTextFont,11,cmsTextSize * t); // Checking position of the extraText after the CMS logo text. - Float_t scale=1; - if (W > H) scale = H/ float(W); // For a rectangle; + Double_t scale=1; + if (W > H) scale = H/ Double_t(W); // For a rectangle; l += 0.043 * (extraTextFont * t * cmsTextSize) * scale; } @@ -494,7 +498,7 @@ void CMS_lumi (TPad *ppad, Int_t iPosX, Float_t scaleLumi) // ---------------------------------------------------------------------- void setRootObjectProperties (TObject *obj, - std::map confs) + std::map confs) // This is a (mostly internal) method to setup the parameters of the provided // object in a "serialized" way. { @@ -509,19 +513,41 @@ void setRootObjectProperties (TObject *obj, else if (xcnf.first=="SetMarkerColor" || xcnf.first=="MarkerColor") dynamic_cast(obj)->SetMarkerColor(Int_t(xcnf.second+0.5)); else if (xcnf.first=="SetMarkerSize" || xcnf.first=="MarkerSize") dynamic_cast(obj)->SetMarkerSize(xcnf.second); else if (xcnf.first=="SetMarkerStyle" || xcnf.first=="MarkerStyle") dynamic_cast(obj)->SetMarkerStyle(Int_t(xcnf.second+0.5)); - - - - } +} +// ---------------------------------------------------------------------- +void copyRootObjectProperties (TObject *obj, + TObject *srcobj, + std::vector proplist, + std::map confs) + // This is an internal method to coordinate the parameters and configuration + // of objects that should have the same. +{ + // Looping over the properties and copy them: + for ( auto xcnf : proplist ) { + if (xcnf=="LineColor") dynamic_cast(obj)->SetLineColor(dynamic_cast(srcobj)->GetLineColor()); + else if (xcnf=="LineStyle") dynamic_cast(obj)->SetLineStyle(dynamic_cast(srcobj)->GetLineStyle()); + else if (xcnf=="LineWidth") dynamic_cast(obj)->SetLineWidth(dynamic_cast(srcobj)->GetLineWidth()); + + else if (xcnf=="FillColor") dynamic_cast(obj)->SetFillColor(dynamic_cast(srcobj)->GetFillColor()); + else if (xcnf=="FillStyle") dynamic_cast(obj)->SetFillStyle(dynamic_cast(srcobj)->GetFillStyle()); + + else if (xcnf=="MarkerColor") dynamic_cast(obj)->SetMarkerColor(dynamic_cast(srcobj)->GetMarkerColor()); + else if (xcnf=="MarkerSize") dynamic_cast(obj)->SetMarkerSize(dynamic_cast(srcobj)->GetMarkerSize()); + else if (xcnf=="MarkerStyle") dynamic_cast(obj)->SetMarkerStyle(dynamic_cast(srcobj)->GetMarkerStyle()); + } + // If we indicated some additional arguments, we use them to further + // configure the object. + if (confs.size()>0) + setRootObjectProperties(obj,confs); } // ---------------------------------------------------------------------- void cmsObjectDraw(TObject *obj, Option_t *option, - std::map confs) + std::map confs) { setRootObjectProperties(obj,confs); @@ -536,8 +562,8 @@ void cmsObjectDraw(TObject *obj, } // ---------------------------------------------------------------------- -TLegend *cmsLeg(Float_t x1, Float_t y1, Float_t x2, Float_t y2, - Float_t textSize, +TLegend *cmsLeg(Double_t x1, Double_t y1, Double_t x2, Double_t y2, + Double_t textSize, Style_t textFont, Color_t textColor, Int_t columns) @@ -586,8 +612,8 @@ void cmsGrid (bool gridon) } // ---------------------------------------------------------------------- -void drawText(const char *text, Float_t posX, Float_t posY, - Font_t font, Short_t align, Float_t size) +void drawText(const char *text, Double_t posX, Double_t posY, + Font_t font, Short_t align, Double_t size) // This is a method to write a Text in a simplified and straightforward // (i.e. user-friendly) way. { TLatex latex; @@ -603,7 +629,7 @@ void drawText(const char *text, Float_t posX, Float_t posY, } // ---------------------------------------------------------------------- -void addCmsLogo (TCmsCanvas *canv,Float_t x0, Float_t y0, Float_t x1, Float_t y1, const char *logofile) +void addCmsLogo (TCmsCanvas *canv,Double_t x0, Double_t y0, Double_t x1, Double_t y1, const char *logofile) // This is a method to draw the CMS logo (that should be set using the // corresponding method or on the fly) in a TPad set at the indicated location // of the currently used TPad. @@ -623,11 +649,11 @@ void addCmsLogo (TCmsCanvas *canv,Float_t x0, Float_t y0, Float_t x1, Float_t y1 // ---------------------------------------------------------------------- TPaveStats *changeStatsBox (TPad *pcanv, - Float_t x1pos, - Float_t y1pos, - Float_t x2pos, - Float_t y2pos, - const std::map &confs) + Double_t x1pos, + Double_t y1pos, + Double_t x2pos, + Double_t y2pos, + const std::map &confs) /// This method allows to modify the properties and similar of the Stats Box in /// the plot. { @@ -647,8 +673,8 @@ TPaveStats *changeStatsBox (TPad *pcanv, } // ---------------------------------------------------------------------- -void changeStatsBox (TPaveStats *pstats, Float_t x1pos, Float_t y1pos, Float_t x2pos, Float_t y2pos, - const std::map &confs) +void changeStatsBox (TPaveStats *pstats, Double_t x1pos, Double_t y1pos, Double_t x2pos, Double_t y2pos, + const std::map &confs) // This method allows to modify the properties and similar of the provided Stats Box. { setRootObjectProperties(pstats,confs); @@ -664,9 +690,9 @@ void changeStatsBox (TPaveStats *pstats, Float_t x1pos, Float_t y1pos, Float_t x // ---------------------------------------------------------------------- TPaveStats *changeStatsBox (TPad *pcanv, const std::string &ipos_x1, - Float_t xscale, - Float_t yscale, - const std::map &confs) + Double_t xscale, + Double_t yscale, + const std::map &confs) // This method allows to modify the properties and similar of the Stats Box in // the plot. Similar to the one with the same name but we use ipos_x0 as a // predefined position identified by using a string. @@ -686,18 +712,18 @@ TPaveStats *changeStatsBox (TPad *pcanv, // The size may be modified depending on the text size. Note that the text // size is 0, it is adapted to the box size (I think) - Float_t textsize = 6*(stbox->GetTextSize()-0.025); + Double_t textsize = 6*(stbox->GetTextSize()-0.025); if (stbox->GetTextSize()==0) textsize = 0; - Float_t xsize = (1-pcanv->GetRightMargin()-pcanv->GetLeftMargin())*xscale; // Note these parameters looses their "x"-"y" nature. - Float_t ysize = (1-pcanv->GetBottomMargin()-pcanv->GetTopMargin())*yscale; + Double_t xsize = (1-pcanv->GetRightMargin()-pcanv->GetLeftMargin())*xscale; // Note these parameters looses their "x"-"y" nature. + Double_t ysize = (1-pcanv->GetBottomMargin()-pcanv->GetTopMargin())*yscale; - Float_t yfactor = 0.05+0.05*stbox->GetListOfLines()->GetEntries(); + Double_t yfactor = 0.05+0.05*stbox->GetListOfLines()->GetEntries(); - Float_t x1=0; - Float_t y1=0; - Float_t x2=0; - Float_t y2=0; + Double_t x1=0; + Double_t y1=0; + Double_t x2=0; + Double_t y2=0; // For "tr": if (a=="tr") { @@ -755,7 +781,7 @@ TPaletteAxis *GetPalette (TH1 *hist) } // ---------------------------------------------------------------------- -void CreateAlternativePalette(Float_t alpha) +void CreateAlternativePalette(Double_t alpha) // Create an alternative color palette for 2D histograms. { Double_t red_values[4] = {0.00, 0.00, 1.00, 0.70}; @@ -783,7 +809,7 @@ void CreateAlternativePalette(Float_t alpha) } // ---------------------------------------------------------------------- -void SetAlternative2DColor (TH2 *hist, TStyle *style, Float_t alpha) +void SetAlternative2DColor (TH2 *hist, TStyle *style, Double_t alpha) // Set an alternative colour palette for a 2D histogram. { // Creating the alternative palette @@ -802,10 +828,10 @@ void SetAlternative2DColor (TH2 *hist, TStyle *style, Float_t alpha) // ---------------------------------------------------------------------- void UpdatePalettePosition (TH2 *hist, TPad *canv, - Float_t X1, - Float_t X2, - Float_t Y1, - Float_t Y2, + Double_t X1, + Double_t X2, + Double_t Y1, + Double_t Y2, Bool_t isNDC) // Adjust the position of the color palette for a 2D histogram. { @@ -837,7 +863,7 @@ void UpdatePalettePosition (TH2 *hist, THStack *buildTHStack (const std::vector &histos, const std::vector &colors, const std::string &stackopt, - const std::map &confs) + const std::map &confs) // This method allows to build a THStack that is returned to the caller so it // may be used for later processing. { @@ -896,7 +922,7 @@ THStack *buildAndDrawTHStack (const std::vector &colors, const std::string &stackopt, - const std::map &confs) + const std::map &confs) // This method allows to build and draw a THStack with a single command. { // We get a vector with the histogram pointers! diff --git a/src/cmsstyle.H b/src/cmsstyle.H index 90f360c..2ec6093 100644 --- a/src/cmsstyle.H +++ b/src/cmsstyle.H @@ -6,6 +6,7 @@ ///
 /// Written by O. Gonzalez (2024_11_19)
 ///                         2025_02_12  Adding the methods for plotting 2-D histograms
+///                         2025_07_11  Routine copyRootObjectProperties added for compatibility with the python version
 /// 
#ifndef CMSSTYLE_CMSSTYLE__H_ @@ -43,10 +44,10 @@ TStyle *cmsStyle = nullptr; std::vector usingPalette2D; // To define a color palette for 2-D histograms -Float_t lumiTextSize = 0.6; // text sizes and text offsets with respect to the top frame in unit of the top margin size -Float_t lumiTextOffset = 0.2; -Float_t cmsTextSize = 0.75; -Float_t cmsTextOffsetX = 0; +Double_t lumiTextSize = 0.6; // text sizes and text offsets with respect to the top frame in unit of the top margin size +Double_t lumiTextOffset = 0.2; +Double_t cmsTextSize = 0.75; +Double_t cmsTextOffsetX = 0; std::string useCmsLogo = ""; // To draw the CMS Logo (filename with path must be provided, may be relative to $CMSSTYLE_DIR) @@ -58,7 +59,7 @@ Font_t additionalInfoFont = 42; std::vector additionalInfo; ///< For extra info, text set under the extra text, for in-frame descriptor. -Float_t extraOverCmsTextSize = 0.76; // ratio of 'CMS' and extra text size +Double_t extraOverCmsTextSize = 0.76; // ratio of 'CMS' and extra text size /// Method to setup the style for the ROOT session! /// Arguments: @@ -84,7 +85,7 @@ void ResetCmsDescriptors (void); /// energy: The centre-of-mass energy value. If 0 the unit part if the used string) /// unit: The energy unit. Defaults to "TeV". /// -void SetEnergy (float energy, const std::string &unit="TeV"); +void SetEnergy (Double_t energy, const std::string &unit="TeV"); /// This method sets the CMS-luminosity related information for the plot. /// Arguments: @@ -93,7 +94,7 @@ void SetEnergy (float energy, const std::string &unit="TeV"); /// run: Name to characterize the run, shown in front of the luminosity /// round_lumi: When set to 0, 1 or 2, used as the number of decimal places for the luminosity number. /// Otherwise ignored. -void SetLumi (Float_t lumi, const std::string &unit="fb", const std::string &run="Run 2", int round_lumi=-1); +void SetLumi (Double_t lumi, const std::string &unit="fb", const std::string &run="Run 2", int round_lumi=-1); /// This method allows to set the CMS text. as needed. /// Arguments: @@ -101,7 +102,7 @@ void SetLumi (Float_t lumi, const std::string &unit="fb", const std::string &run /// font (optional): font to be used for the CMS text. Argument ignored by default. /// size (optional): size to be used for the CMS text. Argument ignored by default. /// -void SetCmsText (const std::string &text, const Font_t &font=0, float size=0); +void SetCmsText (const std::string &text, const Font_t &font=0, Double_t size=0); /// This allows to set the location of the file with the CMS Logo in case we /// want to use that instead of the "CMS" text. @@ -152,7 +153,7 @@ void AppendAdditionalInfo(const std::string &text) {additionalInfo.push_back(tex /// objs: vector with the pointers to the objects to be drawn (or the ones including to /// check the maximum) /// -Float_t cmsReturnMaxY (const std::vector objs); +Double_t cmsReturnMaxY (const std::vector objs); // /////////////////////////////////////////////// @@ -181,18 +182,18 @@ Float_t cmsReturnMaxY (const std::vector objs); /// method takes responsability of its deletion. /// TCmsCanvas *cmsCanvas (const char *canvName, - Float_t x_min, - Float_t x_max, - Float_t y_min, - Float_t y_max, + Double_t x_min, + Double_t x_max, + Double_t y_min, + Double_t y_max, const char *nameXaxis, const char *nameYaxis, Bool_t square = kTRUE, Int_t iPos = 11, - Float_t extraSpace = 0, + Double_t extraSpace = 0, Bool_t with_z_axis = kFALSE, - Float_t scaleLumi = 1.0, - Float_t yTitOffset = -999); + Double_t scaleLumi = 1.0, + Double_t yTitOffset = -999); /// This is the method to draw the "CMS" seal (logo and text) and put the /// luminosity value. @@ -206,18 +207,43 @@ TCmsCanvas *cmsCanvas (const char *canvName, /// Set it to 0 if the CMS logo should be outside the box (top left) /// scaleLumi (optional): Scaling factor for the luminosity text size. Defaults to 1.0 /// -void CMS_lumi (TPad *ppad, Int_t iPosX=11, Float_t scaleLumi=1.0); +void CMS_lumi (TPad *ppad, Int_t iPosX=11, Double_t scaleLumi=1.0); /// This is a (mostly internal) method to setup the parameters of the provided /// object in a "serialized" way. /// /// Arguments: -/// obj: Point to TObject to be configured +/// obj: Pointer to TObject to be configured /// confs: Map with "methods" to be used to configure the object on the fly. /// Only some methods are actually supported (see code for details) /// void setRootObjectProperties (TObject *obj, - std::map confs); + std::map confs); + +/// This method allows to copy the properties of a ROOT object from a reference +/// source (another ROOT object) using a list of named keyword arguments to +/// call the associated methods. +/// +/// The optional confs is used to call the routine setRootObjectProperties for +/// the objects, reducing the amount of calls. +/// +/// This allows to make very efficient the synchronization of the properties +/// between related objects so they appear similar in the plots. +/// +/// (The keyword is obtaining by removing the "Set"/"Get" part of the name of +/// the corresponding methods) +/// +/// Arguments: +/// obj: Pointer to TObject to be configured +/// srcobj: Pointer to TObject from which we are copying the indicated properties +/// proplist: Vector with bames of the properties to be copied. +/// confs (optional): Map with "methods" to be used to configure the object on the fly. +/// Only some methods are actually supported (see code for details) +/// +void copyRootObjectProperties (TObject *obj, + TObject *srcobj, + std::vector proplist, + std::map confs={}); /// This is the basic and most general method to plot things on the plot. /// @@ -229,7 +255,7 @@ void setRootObjectProperties (TObject *obj, /// void cmsObjectDraw (TObject *obj, Option_t *option = "", - std::map confs = std::map()); + std::map confs = std::map()); /// This is the method to setup a legend according to the style! /// @@ -248,8 +274,8 @@ void cmsObjectDraw (TObject *obj, /// Returns: /// A pointer to the defined TLegend. It is created with a new command, so /// the calling routine must take care of the deletion. -TLegend *cmsLeg (Float_t x1, Float_t y1, Float_t x2, Float_t y2, - Float_t textSize=0.04, +TLegend *cmsLeg (Double_t x1, Double_t y1, Double_t x2, Double_t y2, + Double_t textSize=0.04, Style_t textFont=42, Color_t textColor=kBlack, Int_t columns=0); @@ -290,7 +316,7 @@ void cmsGrid (bool gridon); /// align: Code for the alignment of the text with respect to the position /// size: Size of the font /// -void drawText(const char *text, Float_t posX, Float_t posY, Font_t font, Short_t align, Float_t size); +void drawText(const char *text, Double_t posX, Double_t posY, Font_t font, Short_t align, Double_t size); /// This is a method to draw the CMS logo (that should be set using the /// corresponding method or on the fly) in a TPad set at the indicated location @@ -304,7 +330,7 @@ void drawText(const char *text, Float_t posX, Float_t posY, Font_t font, Short_t /// y1: Y position (in relative dimensions) of the upper-left corner of the logo. /// logofile (optional): filename (with path) for the logo picture (see SetCmsLogoFilename for details) /// -void addCmsLogo (TCmsCanvas *canv,Float_t x0, Float_t y0, Float_t x1, Float_t y1, const char *logofile=nullptr); +void addCmsLogo (TCmsCanvas *canv,Double_t x0, Double_t y0, Double_t x1, Double_t y1, const char *logofile=nullptr); /// This method allows to modify the properties and similar of the Stats Box in /// the plot. @@ -319,11 +345,11 @@ void addCmsLogo (TCmsCanvas *canv,Float_t x0, Float_t y0, Float_t x1, Float_t y1 /// Only some methods are actually supported (see code for details) /// TPaveStats *changeStatsBox (TPad *pcanv, - Float_t x1pos=-999, - Float_t y1pos=-999, - Float_t x2pos=-999, - Float_t y2pos=-999, - const std::map &confs = std::map()); + Double_t x1pos=-999, + Double_t y1pos=-999, + Double_t x2pos=-999, + Double_t y2pos=-999, + const std::map &confs = std::map()); /// This method allows to modify the properties and similar of the provided Stats Box. /// @@ -337,11 +363,11 @@ TPaveStats *changeStatsBox (TPad *pcanv, /// Only some methods are actually supported (see code for details) /// void changeStatsBox (TPaveStats *pstats, - Float_t x1pos=-999, - Float_t y1pos=-999, - Float_t x2pos=-999, - Float_t y2pos=-999, - const std::map &confs = std::map()); + Double_t x1pos=-999, + Double_t y1pos=-999, + Double_t x2pos=-999, + Double_t y2pos=-999, + const std::map &confs = std::map()); /// This method allows to modify the properties and similar of the Stats Box in /// the plot. Similar to the one with the same name but we use ipos_x0 as a @@ -374,9 +400,9 @@ void changeStatsBox (TPaveStats *pstats, /// TPaveStats *changeStatsBox (TPad * pcanv, const std::string &ipos_x1, - Float_t xscale=1, - Float_t yscale=1, - const std::map &confs = std::map()); + Double_t xscale=1, + Double_t yscale=1, + const std::map &confs = std::map()); // /////////////////////////////////////////////// // Methods to plot 2-D histograms and related utilities @@ -397,8 +423,8 @@ TPaletteAxis *GetPalette (TH1 *hist); /// Create an alternative color palette for 2D histograms. /// /// Arguments: -/// alpha (Float_t, optional): The transparency value for the palette colors. Defaults to 1 (opaque). -void CreateAlternativePalette (Float_t alpha=1); +/// alpha (Double_t, optional): The transparency value for the palette colors. Defaults to 1 (opaque). +void CreateAlternativePalette (Double_t alpha=1); /// Set an alternative colour palette for a 2D histogram. @@ -406,9 +432,9 @@ void CreateAlternativePalette (Float_t alpha=1); /// Arguments: /// hist (TH2, optional): The 2D histogram to set the colour palette for. /// style (TStyle, optional): The style object to use for setting the palette. -/// alpha (float, optional): The transparency value for the palette colours. Defaults to 1 (opaque). +/// alpha (Double_t, optional): The transparency value for the palette colours. Defaults to 1 (opaque). /// -void SetAlternative2DColor (TH2 *hist=nullptr, TStyle *style=nullptr, Float_t alpha=1); +void SetAlternative2DColor (TH2 *hist=nullptr, TStyle *style=nullptr, Double_t alpha=1); /// Adjust the position of the color palette for a 2D histogram. /// @@ -416,19 +442,19 @@ void SetAlternative2DColor (TH2 *hist=nullptr, TStyle *style=nullptr, Float_t al /// hist (TH2): The 2D histogram to adjust the palette for. /// canv (TPad, optional): The canvas containing the histogram. If provided, /// the palette position will be adjusted based on the canvas margins. -/// X1 (float, optional): The left position of the palette in NDC (0-1) or absolute coordinates. -/// X2 (float, optional): The right position of the palette in NDC (0-1) or absolute coordinates. -/// Y1 (float, optional): The bottom position of the palette in NDC (0-1) or absolute coordinates. -/// Y2 (float, optional): The top position of the palette in NDC (0-1) or absolute coordinates. +/// X1 (Double_t, optional): The left position of the palette in NDC (0-1) or absolute coordinates. +/// X2 (Double_t, optional): The right position of the palette in NDC (0-1) or absolute coordinates. +/// Y1 (Double_t, optional): The bottom position of the palette in NDC (0-1) or absolute coordinates. +/// Y2 (Double_t, optional): The top position of the palette in NDC (0-1) or absolute coordinates. /// isNDC (bool, optional): Whether the provided coordinates are in NDC (True) or absolute /// coordinates (false). Defaults to true. /// void UpdatePalettePosition (TH2 *hist, TPad *canv=nullptr, - Float_t X1=NAN, - Float_t X2=NAN, - Float_t Y1=NAN, - Float_t Y2=NAN, + Double_t X1=NAN, + Double_t X2=NAN, + Double_t Y1=NAN, + Double_t Y2=NAN, Bool_t isNDC=true); // /////////////////////////////////////////////// @@ -466,7 +492,7 @@ void UpdatePalettePosition (TH2 *hist, THStack *buildTHStack (const std::vector &histos, const std::vector &colors=std::vector(), const std::string &stackopt=std::string("STACK"), - const std::map &confs = std::map({{"FillColor",-1},{"FillStyle",1001}}) + const std::map &confs = std::map({{"FillColor",-1},{"FillStyle",1001}}) ); /// This method allows to build and draw a THStack with a single command. @@ -495,7 +521,7 @@ THStack *buildAndDrawTHStack (const std::vector &colors=std::vector(), const std::string &stackopt=std::string("STACK"), - const std::map &confs = std::map({{"FillColor",-1},{"FillStyle",1001}}) + const std::map &confs = std::map({{"FillColor",-1},{"FillStyle",1001}}) ); diff --git a/src/cmsstyle/cmsstyle.py b/src/cmsstyle/cmsstyle.py index 557e66a..a927923 100644 --- a/src/cmsstyle/cmsstyle.py +++ b/src/cmsstyle/cmsstyle.py @@ -371,12 +371,7 @@ def getPettroffColor(color): # -> EColor x = color.split(".") return getattr(getattr(sys.modules[__name__], x[0]), x[1]) - # We try to identify a ROOT color... - try: # Some versions don't identify GetColorByName as a valid method (still used in CMSSW) - return rt.TColor.GetColorByName(color) - except Exception: # We keep for others some basic/common color names - pass - + # Possible standard color if color in ( "kWhite", "kBlack", @@ -395,8 +390,15 @@ def getPettroffColor(color): # -> EColor "kPink", ): return getattr(rt, color) - return None # Not valid color! + # We try to identify a ROOT color... + try: # Some versions don't identify GetColorByName as a valid method (still used in CMSSW) + val = rt.TColor.GetColorByName(color) + if (val>=0): return rt.TColor.GetColorByName(color) + except: # We keep for others some basic/common color names + pass + + return None # Not valid color! # # # # def getPettroffColorSet(ncolors): @@ -1006,8 +1008,17 @@ def cmsCanvas( H = H_ref T = 0.07 * H_ref B = 0.125 * H_ref # Changing this to allow more space in X-title (i.e. subscripts) - L = 0.14 * H_ref # Changing these to leave more space - R = 0.04 * H_ref + L = 0.145 * H_ref # Changing this to leave more space to the title + R = 0.05 * H_ref # Changing this to leave more space + + # The position of the y-axis title may also change a bit the plot: + if yTitOffset is None: + y_offset = 1.2 if square else 0.78 # Changed to fitting larger font + else: + y_offset = yTitOffset + + if (y_offset<1.5): L += y_offset*50-60 # Some adjustment + elif (y_offset<1.8): L += (y_offset-1.4)*35+25 canv = rt.TCanvas(canvName, canvName, 50, 50, W, H) canv.SetFillColor(0) @@ -1024,11 +1035,6 @@ def cmsCanvas( # Draw frame and set axis labels h = canv.DrawFrame(x_min, y_min, x_max, y_max) - if yTitOffset is None: - y_offset = 1.15 if square else 0.78 # Changed to fitting larger font - else: - y_offset = yTitOffset - h.GetYaxis().SetTitleOffset(y_offset) h.GetXaxis().SetTitleOffset(1.05) # Changed to fitting larger font h.GetXaxis().SetTitle(nameXaxis) @@ -1372,6 +1378,8 @@ def cmsObjectDraw(obj, opt="", **kwargs): cmsstyle.cmsObjectDraw(hist,'E',SetLineColor=ROOT.kRed,MarkerStyle=ROOT.kFullCircle) cmsstyle.cmsObjectDraw(hist,'SE',SetLineColor=cmsstyle.p6.kBlue,MarkerStyle=ROOT.kFullCircle) + cmsstyle.cmsObjectDraw(hist,'SCATSAME') # Just 'SCAT' does not work, for some reason... "SCAT" is considered obsolete (?) + Written by O. Gonzalez. Args: @@ -1686,9 +1694,49 @@ def setRootObjectProperties(obj, **kwargs): elif xval is tuple: getattr(obj, method)(*xval) else: - getattr(obj, method)(xval) + try: + getattr(obj,method)(xval) + except TypeError: + if 'Color' in xkey: # The string may be just a color indicated as a name + getattr(obj,method)(getPettroffColor(xval)) + else: + raise +# # # # +def copyRootObjectProperties (obj,srcobj,proplist,**kwargs): + """This method allows to copy the properties of a ROOT object from a reference + source (another ROOT object) using a list of named keyword arguments to + call the associated methods. + + The optional kwargs part is used to call the routine + setRootObjectProperties for the objects, reducing the amount of calls. + + Written by O. Gonzalez. + + This allows to make very efficient the synchronization of the properties + between related objects so they appear similar in the plots. + cmsstyle.setRootObjectProperties(tgraph,hist,['FillColor','FillStyle','SetLineColor']) + + (The keyword is obtaining by removing the "Set"/"Get" part of the name of the corresponding methods) + + Args: + obj (ROOT TObject): ROOT object to which we want to change the properties + srcobj (ROOT TObject): ROOT object from which we are copying the indicated properties + proplist (list of strings): Names of the properties to be copied. + **kwargs: Arbitrary keyword arguments for mofifying the properties of the object using Set methods or similar. + + """ + + for xprp in proplist: # Just proceding with the copy! + getattr(obj,'Set'+xprp)(getattr(srcobj,'Get'+xprp)()) + + # If we indicated some additional arguments, we use them to further + # configure the object. + if len(kwargs)>0: + setRootObjectProperties(obj,**kwargs) + +# # # # def is_valid_hex_color(hexcolor): """ Check if a string represents a valid hexadecimal color code. It also allows other @@ -1735,7 +1783,9 @@ def cmsReturnMaxY(*args): maxval = 0 for xobj in args: - if ( + if (xobj.Class().GetName()=='TEfficiency'): # For efficiencies, we just put 1.2 as maximum! + maxval = 1.19 + elif ( xobj.Class().GetName() == "THStack" ): # For the THStack it is assumed that we will print the sum! maxval = xobj.GetMaximum() @@ -1958,7 +2008,7 @@ def plot_common_legend(self, pad, *args, **kwargs): leg.SetBorderSize(1) leg.SetMargin(0.5) - # Have at most 5 items on the same row + # Have at most 5 items on the same row ndrawables = len(args) ncolumns = ndrawables + 1 if (ndrawables + 1) < 6 else 5 leg.SetNColumns(ncolumns) @@ -2006,13 +2056,13 @@ def plot_common_legend(self, pad, *args, **kwargs): latex.DrawLatex(0.17, 0.94, subtitle) def plot_text( - self, - pad, - text, - textsize=50, - textfont=42, - textalign=33, - xcoord=None, + self, + pad, + text, + textsize=50, + textfont=42, + textalign=33, + xcoord=None, ycoord=None ): # Plotting text is special, we need to be already inside the right pad diff --git a/tests/test_THStack.py b/tests/test_THStack.py index 8340c66..29a8b41 100644 --- a/tests/test_THStack.py +++ b/tests/test_THStack.py @@ -2,7 +2,7 @@ # This python macro plots a THStack # # Written by O. Gonzalez (2024_12_07) -# 2024_12_16 changed to +# 2024_12_16 changed to a new version to handle THStack # import math diff --git a/tests/test_cms2DHisto.C b/tests/test_cms2DHisto.C index cd5e28c..1f435b8 100644 --- a/tests/test_cms2DHisto.C +++ b/tests/test_cms2DHisto.C @@ -37,12 +37,13 @@ void test_cms2DHisto () // Plotting the histogram! cmsstyle::SetEnergy(13.6); cmsstyle::SetLumi(45.00,"fb","Run 3",1); + cmsstyle::SetExtraText(""); TCanvas *c = cmsstyle::cmsCanvas("Testing",0.0,60.0,0.0,60.0, "X var [test]","Y var" ,kTRUE // Square? - ,11 // position of the Logo: 0 is out-of-frame, default is 11. - ,0 // EXtra space, default is 0 + ,0 // position of the Logo: 0 is out-of-frame, default is 11. + ,0 // Etra space, default is 0 ,kTRUE // with_z_axis, dafault is kFALSE ); //cmsstyle::SetCMSPalette(); diff --git a/tests/test_cms2DHisto.py b/tests/test_cms2DHisto.py index 9d1e31c..2bc6b06 100644 --- a/tests/test_cms2DHisto.py +++ b/tests/test_cms2DHisto.py @@ -34,11 +34,12 @@ def test_cms2dHisto (): # Plotting the histogram! cmsstyle.SetEnergy(13.6) cmsstyle.SetLumi(45.00,"fb","Run 3",1) + cmsstyle.SetExtraText("") c = cmsstyle.cmsCanvas("Testing",0.0,60.0,0.0,60.0, "X var [test]","Y var",square=True, - with_z_axis=True - #iPos=0 + with_z_axis=True, + iPos=0 ) # cmsstyle.SetCMSPalette() diff --git a/tests/test_cmsCanvas.C b/tests/test_cmsCanvas.C index cb62d48..e96f70e 100644 --- a/tests/test_cmsCanvas.C +++ b/tests/test_cmsCanvas.C @@ -22,8 +22,8 @@ void test_cmsCanvas () cmsstyle::setCMSStyle(); // Setting the style // Producing the histograms to plot - TH1F h1("test","test",60,0.0,10.0); - TH1F h2("test","test",60,0.0,10.0); + TH1F h1("test1","test1",60,0.0,10.0); + TH1F h2("test2","test2",60,0.0,10.0); for (int i=1;i<=60;++i) { h1.SetBinContent(i,10*exp(-i/5.0)); @@ -45,6 +45,7 @@ void test_cmsCanvas () cmsstyle::SetEnergy(13.6); cmsstyle::SetLumi(45.00,"fb","Run 3",1); + cmsstyle::SetExtraText("wip"); TCanvas *c = cmsstyle::cmsCanvas("Testing",0.0,10.0,0.08,3*cmsstyle::cmsReturnMaxY({&h1,&h2,hdata}), "X var [test]","Y var" diff --git a/tests/test_cmsCanvas.py b/tests/test_cmsCanvas.py index 5120925..1647ed2 100644 --- a/tests/test_cmsCanvas.py +++ b/tests/test_cmsCanvas.py @@ -36,6 +36,7 @@ def test_cmsCanvas (): cmsstyle.SetEnergy(13.6) cmsstyle.SetLumi(45.00,"fb","Run 3",1) + cmsstyle.SetExtraText("wip") c = cmsstyle.cmsCanvas("Testing",0.0,10.0,0.08,3*cmsstyle.cmsReturnMaxY(h1,h2,hdata), "X var [test]","Y var",square=True,