diff --git a/bindings/pyroot/pythonizations/python/ROOT/_pythonization/_roofit/__init__.py b/bindings/pyroot/pythonizations/python/ROOT/_pythonization/_roofit/__init__.py index ca451459f89cc..d5193ecf770ae 100644 --- a/bindings/pyroot/pythonizations/python/ROOT/_pythonization/_roofit/__init__.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_pythonization/_roofit/__init__.py @@ -30,6 +30,7 @@ from ._roodecays import RooDecay, RooBDecay, RooBCPGenDecay, RooBCPEffDecay, RooBMixDecay from ._roogenfitstudy import RooGenFitStudy from ._rooglobalfunc import ( + DataError, FitOptions, Format, Frame, @@ -91,6 +92,7 @@ # list of python functions that are used to pythonize RooGlobalFunc function in RooFit python_roofit_functions = [ + DataError, FitOptions, Format, Frame, diff --git a/bindings/pyroot/pythonizations/python/ROOT/_pythonization/_roofit/_rooglobalfunc.py b/bindings/pyroot/pythonizations/python/ROOT/_pythonization/_roofit/_rooglobalfunc.py index faf45adc19225..d7a5fdd24bf9d 100644 --- a/bindings/pyroot/pythonizations/python/ROOT/_pythonization/_roofit/_rooglobalfunc.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_pythonization/_roofit/_rooglobalfunc.py @@ -55,7 +55,7 @@ @cpp_signature( - "FitOptions(const RooCmdArg& arg1, const RooCmdArg& arg2=RooCmdArg::none()," + "RooFit::FitOptions(const RooCmdArg& arg1, const RooCmdArg& arg2=RooCmdArg::none()," "const RooCmdArg& arg3=RooCmdArg::none(),const RooCmdArg& arg4=RooCmdArg::none()," "const RooCmdArg& arg5=RooCmdArg::none(),const RooCmdArg& arg6=RooCmdArg::none()) ;" ) @@ -71,7 +71,7 @@ def FitOptions(*args, **kwargs): @cpp_signature( - "Format(const char* what, const RooCmdArg& arg1=RooCmdArg::none(), const RooCmdArg& arg2=RooCmdArg::none()," + "RooFit::Format(const char* what, const RooCmdArg& arg1=RooCmdArg::none(), const RooCmdArg& arg2=RooCmdArg::none()," "const RooCmdArg& arg3=RooCmdArg::none(),const RooCmdArg& arg4=RooCmdArg::none()," "const RooCmdArg& arg5=RooCmdArg::none(),const RooCmdArg& arg6=RooCmdArg::none()," "const RooCmdArg& arg7=RooCmdArg::none(),const RooCmdArg& arg8=RooCmdArg::none()) ;" @@ -91,7 +91,7 @@ def Format(*args, **kwargs): @cpp_signature( - "Frame(const RooCmdArg& arg1, const RooCmdArg& arg2=RooCmdArg::none()," + "RooFit::Frame(const RooCmdArg& arg1, const RooCmdArg& arg2=RooCmdArg::none()," "const RooCmdArg& arg3=RooCmdArg::none(), const RooCmdArg& arg4=RooCmdArg::none()," "const RooCmdArg& arg5=RooCmdArg::none(), const RooCmdArg& arg6=RooCmdArg::none()) ;" ) @@ -107,7 +107,7 @@ def Frame(*args, **kwargs): @cpp_signature( - "MultiArg(const RooCmdArg& arg1, const RooCmdArg& arg2," + "RooFit::MultiArg(const RooCmdArg& arg1, const RooCmdArg& arg2," "const RooCmdArg& arg3=RooCmdArg::none(),const RooCmdArg& arg4=RooCmdArg::none()," "const RooCmdArg& arg5=RooCmdArg::none(),const RooCmdArg& arg6=RooCmdArg::none()," "const RooCmdArg& arg7=RooCmdArg::none(),const RooCmdArg& arg8=RooCmdArg::none()) ;" @@ -123,7 +123,7 @@ def MultiArg(*args, **kwargs): return RooFit._MultiArg(*args, **kwargs) -@cpp_signature("YVar(const RooAbsRealLValue& var, const RooCmdArg& arg=RooCmdArg::none()) ;") +@cpp_signature("RooFit::YVar(const RooAbsRealLValue& var, const RooCmdArg& arg=RooCmdArg::none()) ;") def YVar(*args, **kwargs): r"""The YVar() function is pythonized with the command argument pythonization. The keywords must correspond to the CmdArg of the function. @@ -138,7 +138,7 @@ def YVar(*args, **kwargs): return RooFit._YVar(*args, **kwargs) -@cpp_signature("ZVar(const RooAbsRealLValue& var, const RooCmdArg& arg=RooCmdArg::none()) ;") +@cpp_signature("RooFit::ZVar(const RooAbsRealLValue& var, const RooCmdArg& arg=RooCmdArg::none()) ;") def ZVar(*args, **kwargs): r"""The ZVar() function is pythonized with the command argument pythonization. The keywords must correspond to the CmdArg of the function. @@ -153,7 +153,7 @@ def ZVar(*args, **kwargs): return RooFit._ZVar(*args, **kwargs) -@cpp_signature("Slice(std::map const&) ;") +@cpp_signature("RooFit::Slice(std::map const&) ;") def Slice(*args, **kwargs): r"""The Slice function is pythonized for converting python dict to std::map. The keywords must correspond to the CmdArg of the function. @@ -172,9 +172,9 @@ def Slice(*args, **kwargs): @cpp_signature( [ - "Import(const std::map& ) ;", - "Import(const std::map&) ;", - "Import(const std::map&) ;", + "RooFit::Import(const std::map& ) ;", + "RooFit::Import(const std::map&) ;", + "RooFit::Import(const std::map&) ;", ] ) def Import(*args, **kwargs): @@ -193,7 +193,7 @@ def Import(*args, **kwargs): return RooFit._Import(*args, **kwargs) -@cpp_signature("Link(const std::map&) ;") +@cpp_signature("RooFit::Link(const std::map&) ;") def Link(*args, **kwargs): r"""The Link function is pythonized for converting python dict to std::map. The keywords must correspond to the CmdArg of the function. @@ -210,31 +210,52 @@ def Link(*args, **kwargs): return RooFit._Link(*args, **kwargs) -@cpp_signature("LineColor(Color_t color) ;") +@cpp_signature("RooFit::LineColor(Color_t color) ;") def LineColor(color): - # Redefinition of `LineColor` for matplotlib conventions and string arguments. + r"""The `color` argument doesn't necessarily have to be a ROOT color enum value, like `ROOT.kRed`. + Here is what you can also do in PyROOT: + + 1. Pass a string with the enum value name instead, e.g.: + ~~~ {.py} + pdf.plotOn(frame, LineColor="kRed") + ~~~ + 2. Pass a string with the corresponding single-character color code following the matplotlib convention: + ~~~ {.py} + pdf.plotOn(frame, LineColor="r") + ~~~ + 3. Pass a string with the enum value name instead followed by some manipulation of the enum value: + ~~~ {.py} + pdf.plotOn(frame, LineColor="kRed+1") + ~~~ + """ from cppyy.gbl import RooFit return RooFit._LineColor(_string_to_root_attribute(color, _color_map)) -@cpp_signature("FillColor(Color_t color) ;") +@cpp_signature("RooFit::FillColor(Color_t color) ;") def FillColor(color): # Redefinition of `FillColor` for matplotlib conventions and string arguments. from cppyy.gbl import RooFit return RooFit._FillColor(_string_to_root_attribute(color, _color_map)) +# Copy the docstring from LineColor. +FillColor.__doc__ = LineColor.__doc__ + -@cpp_signature("MarkerColor(Color_t color) ;") +@cpp_signature("RooFit::MarkerColor(Color_t color) ;") def MarkerColor(color): # Redefinition of `MarkerColor` for matplotlib conventions and string arguments. from cppyy.gbl import RooFit return RooFit._MarkerColor(_string_to_root_attribute(color, _color_map)) +# Copy the docstring from LineColor. +MarkerColor.__doc__ = LineColor.__doc__ + -@cpp_signature("LineStyle(Style_t style) ;") +@cpp_signature("RooFit::LineStyle(Style_t style) ;") def LineStyle(style): # Redefinition of `LineStyle` for matplotlib conventions and string arguments. from cppyy.gbl import RooFit @@ -242,7 +263,7 @@ def LineStyle(style): return RooFit._LineStyle(_string_to_root_attribute(style, _style_map)) -@cpp_signature("FillStyle(Style_t style) ;") +@cpp_signature("RooFit::FillStyle(Style_t style) ;") def FillStyle(style): # Redefinition of `FillStyle` for matplotlib conventions and string arguments. from cppyy.gbl import RooFit @@ -250,9 +271,51 @@ def FillStyle(style): return RooFit._FillStyle(_string_to_root_attribute(style, {})) -@cpp_signature("MarkerStyle(Style_t style) ;") +@cpp_signature("RooFit::MarkerStyle(Style_t style) ;") def MarkerStyle(style): # Redefinition of `MarkerStyle` for matplotlib conventions and string arguments. from cppyy.gbl import RooFit return RooFit._MarkerStyle(_string_to_root_attribute(style, {})) + + +@cpp_signature("RooFit::DataError(Int_t) ;") +def DataError(etype): + r"""Instead of passing an enum value to this function, you can pass a + string with the name of that enum value, for example: + + ~~~ {.py} + data.plotOn(frame, DataError="SumW2") + # instead of DataError=ROOT.RooAbsData.SumW2 + ~~~ + + If you want to use the `"None"` enum value to disable error plotting, you + can also pass `None` directly instead of passing a string: + + ~~~ {.py} + data.plotOn(frame, DataError=None) + # instead of DataError="None" + ~~~ + """ + # Redefinition of `DataError` to also accept `str` or `NoneType` to get the + # corresponding enum values from RooAbsData.DataError. + from cppyy.gbl import RooFit + + # One of the possible enum values is "None", and we want the user to be + # able to pass None also as a NoneType for convenience. + if etype is None: + etype = "None" + + if isinstance(etype, str): + try: + import ROOT + etype = getattr(ROOT.RooAbsData.ErrorType, etype) + except AttributeError as error: + raise ValueError( + 'Unsupported error type type passed to DataError().' + + ' Supported decay types are : "Poisson", "SumW2", "Auto", "Expected", and None.' + ) + except Exception as exception: + raise exception + + return RooFit._DataError(etype) diff --git a/bindings/pyroot/pythonizations/python/ROOT/_pythonization/_roofit/_utils.py b/bindings/pyroot/pythonizations/python/ROOT/_pythonization/_roofit/_utils.py index 09260a19ff5c6..0b447d61cc654 100644 --- a/bindings/pyroot/pythonizations/python/ROOT/_pythonization/_roofit/_utils.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_pythonization/_roofit/_utils.py @@ -70,7 +70,11 @@ def _string_to_root_attribute(value, lookup_map): return getattr(ROOT, lookup_map[value]) else: try: - return getattr(ROOT, value) + # Here getattr(ROOT, value) would have less overhead, but it's + # also less convenient. With `eval`, the string that is passed + # by the user can also contain postfix operations on the enum + # value, which is often used for columns, e.g. `kGreen+1`. + return eval("ROOT." + value) except: raise ValueError( "Unsupported value passed. The value either has to be the name of an attribute of the ROOT module, or match with one of the following values that get translated to ROOT attributes: {}".format( diff --git a/bindings/pyroot/pythonizations/test/CMakeLists.txt b/bindings/pyroot/pythonizations/test/CMakeLists.txt index 71127af02a33a..0969e6ccdf7d6 100644 --- a/bindings/pyroot/pythonizations/test/CMakeLists.txt +++ b/bindings/pyroot/pythonizations/test/CMakeLists.txt @@ -138,6 +138,7 @@ if(roofit) ROOT_ADD_PYUNITTEST(pyroot_roofit_rooabsreal_ploton roofit/rooabsreal_ploton.py) ROOT_ADD_PYUNITTEST(pyroot_roofit_roolinkedlist roofit/roolinkedlist.py) + ROOT_ADD_PYUNITTEST(pyroot_roofit_rooglobalfunc roofit/rooglobalfunc.py) # NumPy compatibility if(NOT MSVC OR win_broken_tests) diff --git a/bindings/pyroot/pythonizations/test/roofit/rooglobalfunc.py b/bindings/pyroot/pythonizations/test/roofit/rooglobalfunc.py new file mode 100644 index 0000000000000..7ee7fbca0930b --- /dev/null +++ b/bindings/pyroot/pythonizations/test/roofit/rooglobalfunc.py @@ -0,0 +1,33 @@ +import unittest + +import ROOT + + +class TestRooGlobalFunc(unittest.TestCase): + """ + Test for RooGlobalFunc pythonizations. + """ + + def test_color_codes(self): + """Test that the color code pythonizations in the functions like + RooFit.LineColor are working as they should. + """ + + def code(color): + """Get the color code that will be obtained by a given argument + passed to RooFit.LineColor. + """ + return ROOT.RooFit.LineColor(color).getInt(0) + + # Check that general string to enum pythonization works + self.assertEqual(code(ROOT.kRed), code("kRed")) + + # Check that matplotlib-style color strings work + self.assertEqual(code(ROOT.kRed), code("r")) + + # Check that postfix operations applied to ROOT color codes work + self.assertEqual(code(ROOT.kRed+1), code("kRed+1")) + + +if __name__ == "__main__": + unittest.main() diff --git a/documentation/doxygen/print_roofit_pyz_doctrings.py b/documentation/doxygen/print_roofit_pyz_doctrings.py index 1848850d57358..77939c47fa4b4 100644 --- a/documentation/doxygen/print_roofit_pyz_doctrings.py +++ b/documentation/doxygen/print_roofit_pyz_doctrings.py @@ -84,7 +84,7 @@ def write_pyroot_block_for_class(klass): print("") -def write_pyroot_block_for_member_func(func): +def write_pyroot_block_for_function(func): if func.__doc__ is None or not hasattr(func, "_cpp_signature"): return @@ -180,7 +180,10 @@ def print_pyroot_blocks_for_cpp_docs(): for func_name in func_names: func = getattr(python_klass, func_name) - write_pyroot_block_for_member_func(func) + write_pyroot_block_for_function(func) + + for python_function in _roofit.python_roofit_functions: + write_pyroot_block_for_function(python_function) if __name__ == "__main__": diff --git a/roofit/roofitcore/inc/RooGlobalFunc.h b/roofit/roofitcore/inc/RooGlobalFunc.h index 127358380d9dd..d7b83661939c3 100644 --- a/roofit/roofitcore/inc/RooGlobalFunc.h +++ b/roofit/roofitcore/inc/RooGlobalFunc.h @@ -126,7 +126,7 @@ RooCmdArg Cut(const char* cutSpec) ; RooCmdArg Cut(const RooFormulaVar& cutVar) ; RooCmdArg Binning(const RooAbsBinning& binning) ; RooCmdArg Binning(const char* binningName) ; -RooCmdArg Binning(Int_t nBins, Double_t xlo=0., Double_t xhi=0.) ; +RooCmdArg Binning(int nBins, double xlo=0., double xhi=0.) ; RooCmdArg MarkerStyle(Style_t style) ; RooCmdArg MarkerSize(Size_t size) ; RooCmdArg MarkerColor(Color_t color) ; diff --git a/roofit/roofitcore/src/RooAbsData.cxx b/roofit/roofitcore/src/RooAbsData.cxx index a208294aea9c0..24c34663df16a 100644 --- a/roofit/roofitcore/src/RooAbsData.cxx +++ b/roofit/roofitcore/src/RooAbsData.cxx @@ -1724,60 +1724,86 @@ TList* RooAbsData::split(const RooSimultaneous& simpdf, Bool_t createEmptyDataSe /// - A binned dataset will retain its intrinsic binning. /// /// The following optional named arguments can be used to modify the behaviour: +/// \note Please follow the function links in the left column to learn about PyROOT specifics for a given option. /// /// +/// ///
Data representation options -///
`Asymmetry(const RooCategory& c)` Show the asymmetry of the data in given two-state category [F(+)-F(-)] / [F(+)+F(-)]. +///
RooFit::Asymmetry(const RooCategory& c) +/// Show the asymmetry of the data in given two-state category [F(+)-F(-)] / [F(+)+F(-)]. /// Category must have two states with indices -1 and +1 or three states with indices -1,0 and +1. -///
`Efficiency(const RooCategory& c)` Show the efficiency F(acc)/[F(acc)+F(rej)]. Category must have two states with indices 0 and 1 -///
`DataError(RooAbsData::EType)` Select the type of error drawn: +///
RooFit::Efficiency(const RooCategory& c) +/// Show the efficiency F(acc)/[F(acc)+F(rej)]. Category must have two states with indices 0 and 1 +///
RooFit::DataError(Int_t) +/// Select the type of error drawn: /// - `Auto(default)` results in Poisson for unweighted data and SumW2 for weighted data /// - `Poisson` draws asymmetric Poisson confidence intervals. /// - `SumW2` draws symmetric sum-of-weights error ( \f$ \left( \sum w \right)^2 / \sum\left(w^2\right) \f$ ) /// - `None` draws no error bars -///
`Binning(int nbins, double xlo, double xhi)` Use specified binning to draw dataset -///
`Binning(const RooAbsBinning&)` Use specified binning to draw dataset -///
`Binning(const char* name)` Use binning with specified name to draw dataset -///
`RefreshNorm(Bool_t flag)` Force refreshing for PDF normalization information in frame. +///
RooFit::Binning(int nbins, double xlo, double xhi) +/// Use specified binning to draw dataset +///
RooFit::Binning(const RooAbsBinning&) +/// Use specified binning to draw dataset +///
RooFit::Binning(const char* name) +/// Use binning with specified name to draw dataset +///
RooFit::RefreshNorm() +/// Force refreshing for PDF normalization information in frame. /// If set, any subsequent PDF will normalize to this dataset, even if it is /// not the first one added to the frame. By default only the 1st dataset /// added to a frame will update the normalization information -///
`Rescale(Double_t f)` Rescale drawn histogram by given factor. -///
`Cut(const char*)` Only plot entries that pass the given cut. -/// Apart from cutting in continuous variables `Cut("x>5")`, this can also be used to plot a specific -/// category state. Use something like `Cut("myCategory == myCategory::stateA")`, where -/// `myCategory` resolves to the state number for a given entry and -/// `myCategory::stateA` resolves to the state number of the state named "stateA". +///
RooFit::Rescale(Double_t f) +/// Rescale drawn histogram by given factor. +///
RooFit::Cut(const char*) +/// Only plot entries that pass the given cut. +/// Apart from cutting in continuous variables `Cut("x>5")`, this can also be used to plot a specific +/// category state. Use something like `Cut("myCategory == myCategory::stateA")`, where +/// `myCategory` resolves to the state number for a given entry and +/// `myCategory::stateA` resolves to the state number of the state named "stateA". /// -///
`CutRange(const char*)` Only plot data from given range. Separate multiple ranges with ",". -/// \note This often requires passing the normalisation when plotting the PDF because RooFit does not save -/// how many events were being plotted (it will only work for cutting slices out of uniformly distributed variables). +///
RooFit::CutRange(const char*) +/// Only plot data from given range. Separate multiple ranges with ",". +/// \note This often requires passing the normalisation when plotting the PDF because RooFit does not save +/// how many events were being plotted (it will only work for cutting slices out of uniformly distributed +/// variables). /// ``` -/// data->plotOn(frame01, CutRange("SB1")); -/// const double nData = data->sumEntries("", "SB1"); -/// // Make clear that the target normalisation is nData. The enumerator NumEvent -/// // is needed to switch between relative and absolute scaling. -/// model.plotOn(frame01, Normalization(nData, RooAbsReal::NumEvent), -/// ProjectionRange("SB1")); +/// data->plotOn(frame01, CutRange("SB1")); +/// const double nData = data->sumEntries("", "SB1"); +/// // Make clear that the target normalisation is nData. The enumerator NumEvent +/// // is needed to switch between relative and absolute scaling. +/// model.plotOn(frame01, Normalization(nData, RooAbsReal::NumEvent), +/// ProjectionRange("SB1")); /// ``` /// ///
Histogram drawing options -///
`DrawOption(const char* opt)` Select ROOT draw option for resulting TGraph object -///
`LineStyle(Int_t style)` Select line style by ROOT line style code, default is solid -///
`LineColor(Int_t color)` Select line color by ROOT color code, default is black -///
`LineWidth(Int_t width)` Select line with in pixels, default is 3 -///
`MarkerStyle(Int_t style)` Select the ROOT marker style, default is 21 -///
`MarkerColor(Int_t color)` Select the ROOT marker color, default is black -///
`MarkerSize(Double_t size)` Select the ROOT marker size -///
`FillStyle(Int_t style)` Select fill style, default is filled. -///
`FillColor(Int_t color)` Select fill color by ROOT color code -///
`XErrorSize(Double_t frac)` Select size of X error bar as fraction of the bin width, default is 1 -/// +///
RooFit::DrawOption(const char* opt) +/// Select ROOT draw option for resulting TGraph object +///
RooFit::LineStyle(Style_t style) +/// Select line style by ROOT line style code, default is solid +///
RooFit::LineColor(Color_t color) +/// Select line color by ROOT color code, default is black +///
RooFit::LineWidth(Width_t width) +/// Select line with in pixels, default is 3 +///
RooFit::MarkerStyle(Style_t style) +/// Select the ROOT marker style, default is 21 +///
RooFit::MarkerColor(Color_t color) +/// Select the ROOT marker color, default is black +///
RooFit::MarkerSize(Size_t size) +/// Select the ROOT marker size +///
RooFit::FillStyle(Style_t style) +/// Select fill style, default is filled. +///
RooFit::FillColor(Color_t color) +/// Select fill color by ROOT color code +///
RooFit::XErrorSize(Double_t frac) +/// Select size of X error bar as fraction of the bin width, default is 1 /// ///
Misc. other options -///
`Name(const chat* name)` Give curve specified name in frame. Useful if curve is to be referenced later -///
`Invisible()` Add curve to frame, but do not display. Useful in combination AddTo() -///
`AddTo(const char* name, double_t wgtSelf, double_t wgtOther)` Add constructed histogram to already existing histogram with given name and relative weight factors +///
RooFit::Name(const char* name) +/// Give curve specified name in frame. Useful if curve is to be referenced later +///
RooFit::Invisible() +/// Add curve to frame, but do not display. Useful in combination AddTo() +///
RooFit::AddTo(const char* name, double wgtSel, double wgtOther) +/// Add constructed histogram to already existing histogram with given name and relative weight factors +/// ///
RooPlot* RooAbsData::plotOn(RooPlot* frame, const RooLinkedList& argList) const diff --git a/roofit/roofitcore/src/RooGlobalFunc.cxx b/roofit/roofitcore/src/RooGlobalFunc.cxx index 50ecd106cf495..a1a6c3f8ad724 100644 --- a/roofit/roofitcore/src/RooGlobalFunc.cxx +++ b/roofit/roofitcore/src/RooGlobalFunc.cxx @@ -124,12 +124,11 @@ namespace RooFit { RooCmdArg Cut(const RooFormulaVar& cutVar) { return RooCmdArg("CutVar",0,0,0,0,0,0,&cutVar,0) ; } RooCmdArg Binning(const RooAbsBinning& binning) { return RooCmdArg("Binning",0,0,0,0,0,0,&binning,0) ;} RooCmdArg Binning(const char* binningName) { return RooCmdArg("BinningName",0,0,0,0,binningName,0,0,0) ;} - RooCmdArg Binning(Int_t nBins, Double_t xlo, Double_t xhi) { return RooCmdArg("BinningSpec",nBins,0,xlo,xhi,0,0,0,0) ;} + RooCmdArg Binning(int nBins, double xlo, double xhi) { return RooCmdArg("BinningSpec",nBins,0,xlo,xhi,0,0,0,0) ;} RooCmdArg MarkerStyle(Style_t style) { return RooCmdArg("MarkerStyle",style,0,0,0,0,0,0,0) ; } RooCmdArg MarkerSize(Size_t size) { return RooCmdArg("MarkerSize",0,0,size,0,0,0,0,0) ; } RooCmdArg MarkerColor(Color_t color) { return RooCmdArg("MarkerColor",color,0,0,0,0,0,0,0) ; } RooCmdArg CutRange(const char* rangeName) { return RooCmdArg("CutRange",0,0,0,0,rangeName,0,0,0) ; } - RooCmdArg AddTo(const char* name) { return RooCmdArg("AddTo",0,0,0,0,name,0,0,0) ; } RooCmdArg XErrorSize(Double_t width) { return RooCmdArg("XErrorSize",0,0,width,0,0,0,0,0) ; } RooCmdArg RefreshNorm() { return RooCmdArg("RefreshNorm",1,0,0,0,0,0,0,0) ; } RooCmdArg Efficiency(const RooCategory& cat) { return RooCmdArg("Efficiency",0,0,0,0,0,0,&cat,0) ; } diff --git a/tutorials/roofit/rf102_dataimport.py b/tutorials/roofit/rf102_dataimport.py index db2deb3a61f0d..3db7658485118 100644 --- a/tutorials/roofit/rf102_dataimport.py +++ b/tutorials/roofit/rf102_dataimport.py @@ -76,7 +76,7 @@ def makeTTree(): # but e.g. is a sum of weighted events) you can data with symmetric 'sum-of-weights' error instead # (same error bars as shown by ROOT) frame2 = x.frame(Title="Imported ROOT.TH1 with internal errors") -dh.plotOn(frame2, DataError=ROOT.RooAbsData.SumW2) +dh.plotOn(frame2, DataError="SumW2") gauss.plotOn(frame2) # Please note that error bars shown (Poisson or SumW2) are for visualization only, the are NOT used diff --git a/tutorials/roofit/rf107_plotstyles.py b/tutorials/roofit/rf107_plotstyles.py index 19ea6368c7166..2cc57c075e807 100644 --- a/tutorials/roofit/rf107_plotstyles.py +++ b/tutorials/roofit/rf107_plotstyles.py @@ -41,7 +41,7 @@ # --------------------------------------- # Use sqrt(sum(weights^2)) error instead of Poisson errors -data.plotOn(frame1, DataError=ROOT.RooAbsData.SumW2) +data.plotOn(frame1, DataError="SumW2") # Remove horizontal error bars data.plotOn(frame2, XErrorSize=0) @@ -50,7 +50,7 @@ data.plotOn(frame3, MarkerColor="b", LineColor="b") # Filled bar chart -data.plotOn(frame4, DrawOption="B", DataError=ROOT.RooAbsData.ErrorType(2), XErrorSize=0, FillColor="kGray") +data.plotOn(frame4, DrawOption="B", DataError=None, XErrorSize=0, FillColor="kGray") # Function plotting styles # ----------------------------------------------- diff --git a/tutorials/roofit/rf109_chi2residpull.py b/tutorials/roofit/rf109_chi2residpull.py index 96b64a4633c14..8fdce0ddad0ad 100644 --- a/tutorials/roofit/rf109_chi2residpull.py +++ b/tutorials/roofit/rf109_chi2residpull.py @@ -35,8 +35,8 @@ # --------------------------------------------------------------------------- # Overlay projection of gauss with sigma=3.15 on data with sigma=3.0 -frame1 = x.frame(ROOT.RooFit.Title("Data with distorted Gaussian pdf"), ROOT.RooFit.Bins(40)) -data.plotOn(frame1, ROOT.RooFit.DataError(ROOT.RooAbsData.SumW2)) +frame1 = x.frame(Title="Data with distorted Gaussian pdf", Bins=40) +data.plotOn(frame1, DataError="SumW2") gauss.plotOn(frame1) # Calculate chi^2 @@ -58,12 +58,12 @@ # Create a frame to draw the residual distribution and add the # distribution to the frame -frame2 = x.frame(ROOT.RooFit.Title("Residual Distribution")) +frame2 = x.frame(Title="Residual Distribution") frame2.addPlotable(hresid, "P") # Create a frame to draw the pull distribution and add the distribution to # the frame -frame3 = x.frame(ROOT.RooFit.Title("Pull Distribution")) +frame3 = x.frame(Title="Pull Distribution") frame3.addPlotable(hpull, "P") c = ROOT.TCanvas("rf109_chi2residpull", "rf109_chi2residpull", 900, 300) diff --git a/tutorials/roofit/rf403_weightedevts.py b/tutorials/roofit/rf403_weightedevts.py index 4207fecc25325..7dfaa22c9e008 100644 --- a/tutorials/roofit/rf403_weightedevts.py +++ b/tutorials/roofit/rf403_weightedevts.py @@ -86,10 +86,10 @@ # --------------------------------------------------------------- # Construct plot frame -frame = x.frame(ROOT.RooFit.Title("Unbinned ML fit, chi^2 fit to weighted data")) +frame = x.frame(Title="Unbinned ML fit, chi^2 fit to weighted data") # Plot data using sum-of-weights-squared error rather than Poisson errors -wdata.plotOn(frame, ROOT.RooFit.DataError(ROOT.RooAbsData.SumW2)) +wdata.plotOn(frame, DataError="SumW2") # Overlay result of 2nd order polynomial fit to weighted data p2.plotOn(frame) @@ -123,7 +123,7 @@ # NB: Within the usual approximations of a chi2 fit, chi2 fit to weighted # data using sum-of-weights-squared errors does give correct error # estimates -chi2 = ROOT.RooChi2Var("chi2", "chi2", p2, binnedData, ROOT.RooFit.DataError(ROOT.RooAbsData.SumW2)) +chi2 = ROOT.RooChi2Var("chi2", "chi2", p2, binnedData, ROOT.RooFit.DataError("SumW2")) m = ROOT.RooMinimizer(chi2) m.migrad() m.hesse() diff --git a/tutorials/roofit/rf711_lagrangianmorph.py b/tutorials/roofit/rf711_lagrangianmorph.py index 73a5ebc8cf244..8183a8e5a3bf5 100644 --- a/tutorials/roofit/rf711_lagrangianmorph.py +++ b/tutorials/roofit/rf711_lagrangianmorph.py @@ -34,7 +34,7 @@ # Inputs to setup config # -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - -infilename = ROOT.gROOT.GetTutorialDir().Data() + "/roofit/input_histos_rf_lagrangianmorph.root"; +infilename = ROOT.gROOT.GetTutorialDir().Data() + "/roofit/input_histos_rf_lagrangianmorph.root" par = "cHq3" samplelist = ["SM_NPsq0", "cHq3_NPsq1", "cHq3_NPsq2"] @@ -71,45 +71,28 @@ input_hists = {sample: ROOT.TFile.Open(infilename).Get(sample).FindObject(observablename) for sample in samplelist} input_datahists = { - sample: ROOT.RooDataHist("dh_" + sample, "dh_" + sample, [obsvar], input_hists[sample]) - for sample in samplelist + sample: ROOT.RooDataHist("dh_" + sample, "dh_" + sample, [obsvar], input_hists[sample]) for sample in samplelist } # Plot input templates # -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - frame0 = obsvar.frame(Title="Input templates for p_{T}^{V}") -for sample, color in zip(samplelist, [ROOT.kBlack, ROOT.kRed, ROOT.kBlue]): +for sample, color in zip(samplelist, "krb"): input_datahists[sample].plotOn(frame0, Name=sample, LineColor=color, MarkerColor=color, MarkerSize=1) # Plot morphed templates for cHq3=0.01,0.25,0.5 # -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - frame1 = obsvar.frame(Title="Morphed templates for selected values") -morph_datahist_0p01.plotOn( - frame1, - Name="morph_dh_cHq3=0.01", +plot_args = dict( DrawOption="C", - LineColor=ROOT.kGreen, - DataError=getattr(ROOT.RooAbsData, "None"), - XErrorSize=0, -) -morph_datahist_0p25.plotOn( - frame1, - Name="morph_dh_cHq3=0.25", - DrawOption="C", - LineColor=ROOT.kGreen + 1, - DataError=getattr(ROOT.RooAbsData, "None"), - XErrorSize=0, -) -morph_datahist_0p5.plotOn( - frame1, - Name="morph_dh_cHq3=0.5", - DrawOption="C", - LineColor=ROOT.kGreen + 2, - DataError=getattr(ROOT.RooAbsData, "None"), + DataError=None, XErrorSize=0, ) +morph_datahist_0p01.plotOn(frame1, Name="morph_dh_cHq3=0.01", LineColor="kGreen", **plot_args) +morph_datahist_0p25.plotOn(frame1, Name="morph_dh_cHq3=0.25", LineColor="kGreen+1", **plot_args) +morph_datahist_0p5.plotOn(frame1, Name="morph_dh_cHq3=0.5", LineColor="kGreen+2", **plot_args) # Create wrapped pdf to generate 2D dataset of cHq3 as a function of pTV # -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - diff --git a/tutorials/roofit/rf712_lagrangianmorphfit.py b/tutorials/roofit/rf712_lagrangianmorphfit.py index 3e598b8573320..4b3cd6ef6d784 100644 --- a/tutorials/roofit/rf712_lagrangianmorphfit.py +++ b/tutorials/roofit/rf712_lagrangianmorphfit.py @@ -32,7 +32,7 @@ # Inputs to setup config # -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - -infilename = ROOT.gROOT.GetTutorialDir().Data() + "/roofit/input_histos_rf_lagrangianmorph.root"; +infilename = ROOT.gROOT.GetTutorialDir().Data() + "/roofit/input_histos_rf_lagrangianmorph.root" par = "cHq3" samplelist = [ "SM_NPsq0", @@ -105,8 +105,8 @@ frame0, Name="postfit_dist", DrawOption="C", - LineColor=ROOT.kBlue, - DataError=getattr(ROOT.RooAbsData, "None"), + LineColor="b", + DataError=None, XErrorSize=0, ) pseudo_dh.plotOn(frame0, Name="input")