Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-21 09:25:16

0001 /*
0002  * Project: xRooFit
0003  * Author:
0004  *   Will Buttinger, RAL 2022
0005  *
0006  * Copyright (c) 2022, CERN
0007  *
0008  * Redistribution and use in source and binary forms,
0009  * with or without modification, are permitted according to the terms
0010  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
0011  */
0012 
0013 #include "Config.h"
0014 
0015 #ifdef XROOFIT_USE_PRAGMA_ONCE
0016 #pragma once
0017 #endif
0018 #if !defined(XROOFIT_XROONODE_H) || defined(XROOFIT_USE_PRAGMA_ONCE)
0019 #ifndef XROOFIT_USE_PRAGMA_ONCE
0020 #define XROOFIT_XROONODE_H
0021 #endif
0022 
0023 #include "TNamed.h"
0024 #include <vector>
0025 #include <functional>
0026 
0027 class RooWorkspace;
0028 class RooAbsReal;
0029 class TH1;
0030 class RooAbsLValue;
0031 class RooArgList;
0032 class RooAbsBinning;
0033 class RooFitResult;
0034 class TGraph;
0035 class TAxis;
0036 class TGListTreeItem;
0037 class TGListTree;
0038 class TVirtualPad;
0039 class TStyle;
0040 
0041 #include "xRooFit.h"
0042 #include "RooLinkedList.h"
0043 #include "RooCmdArg.h"
0044 #include "TQObject.h"
0045 #include "TMatrixDSym.h"
0046 
0047 BEGIN_XROOFIT_NAMESPACE
0048 
0049 class xRooNode;
0050 class xRooNLLVar;
0051 
0052 class xRooNode : public TNamed, public std::vector<std::shared_ptr<xRooNode>> {
0053 
0054 public:
0055    // functions of form value = f(orig,nom,nom_err)
0056    // e.g. f = ratio would be simply orig/nom
0057    // bool indicates if should be symmetrized
0058    static std::map<std::string, std::tuple<std::function<double(double, double, double)>, bool>> auxFunctions;
0059    /** @private */
0060    static void SetAuxFunction(const char *title, const std::function<double(double, double, double)> &func,
0061                               bool symmetrize = false);
0062 
0063    // this function is here because couldn't figure out how to check a null shared_ptr in pyroot
0064    /** @private */
0065    static inline bool isNull(const std::shared_ptr<xRooNode> &x) { return x == nullptr; }
0066 
0067    // name of the node needn't match the name of the component that it points to
0068    // the name of the node is how it is identified inside its parent
0069    // In c++17 for constructors with a Node2& parent, could look at using shared_from_this and if it throws except then
0070    // construct make_shared<Node2>(parent)
0071    xRooNode(const char *type, const char *name, const char *title = "");
0072 
0073    /** @private */
0074    template <typename T>
0075    xRooNode(const char *name, const char *title) : TNamed(name, title), fComp(std::make_shared<T>())
0076    {
0077       if (auto x = get<TNamed>(); x) {
0078          x->SetNameTitle(name, title);
0079       }
0080    }
0081    xRooNode(const char *name = "", const std::shared_ptr<TObject> &comp = nullptr,
0082             const std::shared_ptr<xRooNode> &parent = nullptr);
0083 
0084    /** @private */
0085    xRooNode(const char *name, const std::shared_ptr<TObject> &comp, const xRooNode &parent)
0086       : xRooNode(name, comp, std::make_shared<xRooNode>(parent))
0087    {
0088    }
0089 
0090    /** @private */
0091    xRooNode(const char *name, const TObject &comp, const std::shared_ptr<xRooNode> &parent)
0092       : xRooNode(name, std::shared_ptr<TObject>(const_cast<TObject *>(&comp), [](TObject *) {}), parent)
0093    {
0094    } // needed to ensure passing a shared_ptr<Node2> for the parent doesnt become Node2(shared_ptr<Node2>) as parent
0095      // because of Node2(shared_ptr<TObject>) constructor
0096    /** @private */
0097    xRooNode(const char *name, const TObject &comp, const xRooNode &parent)
0098       : xRooNode(name, std::shared_ptr<TObject>(const_cast<TObject *>(&comp), [](TObject *) {}), parent)
0099    {
0100    }
0101    /** @private */
0102    xRooNode(const TObject &comp, const std::shared_ptr<xRooNode> &parent = nullptr);
0103    /** @private */
0104    xRooNode(const TObject &comp, const xRooNode &parent) : xRooNode(comp, std::make_shared<xRooNode>(parent)) {}
0105    /** @private */
0106    xRooNode(const std::shared_ptr<TObject> &comp, const std::shared_ptr<xRooNode> &parent = nullptr);
0107    template <typename T>
0108    /** @private */
0109    xRooNode(const std::shared_ptr<T> &comp, const std::shared_ptr<xRooNode> &parent = nullptr)
0110       : xRooNode(std::dynamic_pointer_cast<TObject>(comp), parent)
0111    {
0112    }
0113    /** @private */
0114    template <typename T>
0115    xRooNode(const std::shared_ptr<T> &comp, const xRooNode &parent)
0116       : xRooNode(std::dynamic_pointer_cast<TObject>(comp), std::make_shared<xRooNode>(parent))
0117    {
0118    }
0119    /** @private */
0120    template <typename T>
0121    xRooNode(const std::shared_ptr<const T> &comp, const std::shared_ptr<xRooNode> &parent = nullptr)
0122       : xRooNode(std::dynamic_pointer_cast<TObject>(std::const_pointer_cast<T>(comp)), parent)
0123    {
0124    }
0125    /** @private */
0126    template <typename T>
0127    xRooNode(const std::shared_ptr<const T> &comp, const xRooNode &parent)
0128       : xRooNode(std::dynamic_pointer_cast<TObject>(std::const_pointer_cast<T>(comp)),
0129                  std::make_shared<xRooNode>(parent))
0130    {
0131    }
0132    /** @private */
0133    xRooNode(double value);
0134 
0135    ~xRooNode() override;
0136 
0137    void SetName(const char *name) override;   // *MENU*
0138    void SetTitle(const char *title) override; // *MENU*
0139 
0140    /** @private */
0141    const char *GetNodeType() const;
0142 
0143    /** @private */
0144    explicit operator bool() const { return strlen(GetName()) || get(); } // the 'null' Component is the empty string
0145 
0146    // at doesn't do an initial browse of the object, unlike [] operator
0147    const std::shared_ptr<xRooNode> &at(size_t idx, bool browseResult = true) const
0148    {
0149       IsFolder();
0150       auto &out = std::vector<std::shared_ptr<xRooNode>>::at(idx);
0151       if (browseResult && out)
0152          out->browse();
0153       return out;
0154    }
0155    std::shared_ptr<xRooNode> at(const std::string &name, bool browseResult = true) const;
0156 
0157    RooArgList argList() const;
0158 
0159    std::shared_ptr<xRooNode>
0160    find(const std::string &name, bool browseResult = true) const; // same as at but return nullptr if not found
0161    bool contains(const std::string &name) const; // doesn't trigger a browse of the found object, unlike find
0162 
0163    // most users should use these methods: will do an initial browse and will browse the returned object too
0164    std::shared_ptr<xRooNode> operator[](size_t idx) { return at(idx); }
0165    std::shared_ptr<xRooNode> operator[](const std::string &name); // will create a new node if not existing, unlike 'at'
0166 
0167    // custom iterator to ensure children are auto-browsed as we iterate through
0168    class xRooNodeIterator : public std::vector<std::shared_ptr<xRooNode>>::const_iterator {
0169    public:
0170       xRooNodeIterator(std::vector<std::shared_ptr<xRooNode>>::const_iterator itr)
0171          : std::vector<std::shared_ptr<xRooNode>>::const_iterator(itr)
0172       {
0173       }
0174       std::iterator_traits<const std::shared_ptr<xRooNode> *>::reference operator*() const
0175       {
0176          const std::shared_ptr<xRooNode> &out = std::vector<std::shared_ptr<xRooNode>>::const_iterator::operator*();
0177          if (out->get() && out->empty()) {
0178             out->browse();
0179          }
0180          return std::vector<std::shared_ptr<xRooNode>>::const_iterator::operator*();
0181       }
0182       bool operator!=(xRooNodeIterator const &b) const
0183       {
0184          const std::vector<std::shared_ptr<xRooNode>>::const_iterator &aa = (*this);
0185          const std::vector<std::shared_ptr<xRooNode>>::const_iterator &bb = b;
0186          return aa != bb;
0187       };
0188       xRooNodeIterator const &operator++()
0189       {
0190          std::vector<std::shared_ptr<xRooNode>>::const_iterator::operator++();
0191          return *this;
0192       }
0193       bool operator==(xRooNodeIterator const &b) const
0194       {
0195          const std::vector<std::shared_ptr<xRooNode>>::const_iterator &aa = (*this);
0196          const std::vector<std::shared_ptr<xRooNode>>::const_iterator &bb = b;
0197          return aa == bb;
0198       };
0199    };
0200    auto begin() const -> xRooNodeIterator
0201    {
0202       // this update is to resolve need for calling browse() before iterating, e.g.
0203       //      for(auto a : xRooNode(b).browse()) ...
0204       // can now become the more natural:
0205       //      for(auto a : xRooNode(b)) ...
0206       // but would still need e.g. xRooNode(s).browse().size() rather than xRooNode(s).size() which would give 0 for
0207       // unpopulated case
0208       static bool browseLock =
0209          false; // need for blocking recursive calls to browse (since browse method uses the iterators)
0210       if (!browseLock && get() && empty()) {
0211          browseLock = true;
0212          const_cast<xRooNode &>(*this).browse();
0213          browseLock = false;
0214       }
0215       return xRooNodeIterator(std::vector<std::shared_ptr<xRooNode>>::begin());
0216    }
0217    auto end() const -> xRooNodeIterator { return xRooNodeIterator(std::vector<std::shared_ptr<xRooNode>>::end()); }
0218 
0219    // needed in pyROOT to avoid it creating iterators that follow the 'get' to death
0220    //   auto begin() const -> decltype(std::vector<std::shared_ptr<xRooNode>>::begin())
0221    //   {
0222    //      return std::vector<std::shared_ptr<xRooNode>>::begin();
0223    //   }
0224    //   auto end() const -> decltype(std::vector<std::shared_ptr<xRooNode>>::end())
0225    //   {
0226    //      return std::vector<std::shared_ptr<xRooNode>>::end();
0227    //   }
0228 
0229    void Browse(TBrowser *b = nullptr) override; // will browse the children that aren't "null" nodes
0230    /** @private */
0231    bool IsFolder() const override;
0232    /** @private */
0233    const char *GetIconName() const override;
0234    void Inspect() const override; // *MENU*
0235 
0236    /** @private */
0237    xRooNode &browse(); // refreshes child nodes
0238 
0239    /** @private */
0240    std::string GetPath() const;
0241    void Print(Option_t *opt = "") const override; // *MENU*
0242    // void Reverse() {
0243    // std::reverse(std::vector<std::shared_ptr<Node2>>::begin(),std::vector<std::shared_ptr<Node2>>::end()); } // *MENU*
0244 
0245    xRooNode &operator=(const TObject &o);
0246 
0247    TObject *get() const { return fComp.get(); }
0248    template <typename T>
0249    T *get() const
0250    {
0251       return dynamic_cast<T *>(get());
0252    }
0253    /** @private */
0254    TObject *xget() const { return xget<TObject>(); }
0255    template <typename T>
0256    T *xget() const
0257    {
0258       for (auto &c : fBrowsables) {
0259          if (strcmp(c->GetName(), ".memory") == 0) {
0260             return c->get<T>();
0261          }
0262       }
0263       return nullptr;
0264    }
0265 
0266    TObject *operator->() const { return get(); }
0267 
0268    RooWorkspace *ws() const;
0269 
0270    /** @private */
0271    std::shared_ptr<TObject>
0272    acquire(const std::shared_ptr<TObject> &arg, bool checkFactory = false, bool mustBeNew = false);
0273    // common pattern for 'creating' an acquired object
0274    /** @private */
0275    template <typename T, typename... Args>
0276    std::shared_ptr<T> acquire(Args &&...args)
0277    {
0278       return std::dynamic_pointer_cast<T>(acquire(std::make_shared<T>(std::forward<Args>(args)...)));
0279    }
0280    /** @private */
0281    template <typename T, typename T2, typename... Args>
0282    // looser version of above ... first template type says what type to return
0283    // allows returning different type to the one requested in T2 (e.g. ok to get RooConstVar when acquire a RooRealVar)
0284    std::shared_ptr<T> acquire2(Args &&...args)
0285    {
0286       return std::dynamic_pointer_cast<T>(acquire(std::make_shared<T2>(std::forward<Args>(args)...)));
0287    }
0288    /** @private */
0289    template <typename T, typename... Args>
0290    std::shared_ptr<T> acquireNew(Args &&...args)
0291    {
0292       return std::dynamic_pointer_cast<T>(acquire(std::make_shared<T>(std::forward<Args>(args)...), false, true));
0293    }
0294    /** @private */
0295    std::shared_ptr<TObject> getObject(const std::string &name, const std::string &type = "") const;
0296    /** @private */
0297    template <typename T>
0298    std::shared_ptr<T> getObject(const std::string &name) const
0299    {
0300       return std::dynamic_pointer_cast<T>(getObject(name, T::Class_Name()));
0301    }
0302 
0303    /** @private */
0304    xRooNode shallowCopy(const std::string &name, std::shared_ptr<xRooNode> parent = nullptr);
0305    /** @private */
0306    std::shared_ptr<TObject> convertForAcquisition(xRooNode &acquirer, const char *opt = "") const;
0307 
0308    xRooNode vars() const;   // obs,pars
0309    xRooNode obs() const;    // robs and globs
0310    xRooNode robs() const;   // just the regular obs
0311    xRooNode globs() const;  // just the global obs
0312    xRooNode pars() const;   // poi, np, and pp (prespecified pars)
0313    xRooNode floats() const; // float poi or np
0314    xRooNode consts() const; // just const poi or np
0315 
0316    xRooNode poi() const; // parameters of interest
0317    xRooNode np() const;  // nuisance parameters (non-poi floatables)
0318    xRooNode pp() const;  // preset/prespecified parameters
0319 
0320    xRooNode components() const; // additive children
0321    xRooNode factors() const;    // multiplicative children
0322    xRooNode variations() const; // interpolated children (are bins a form of variation?)
0323    xRooNode coefs(bool recurse = false) const;
0324    xRooNode coords(bool setVals = true) const; // will move to the coords in the process if setVals=true
0325    xRooNode bins() const;
0326 
0327    xRooNode constraints() const; // pdfs other than the node's parent pdf where the deps of this node appear
0328    xRooNode datasets()
0329       const; // datasets corresponding to this pdf (parent nodes that do observable selections automatically applied)
0330 
0331    xRooNode parents() const; // the clients of this node
0332    xRooNode args() const;    // all the nodes underneath this node
0333 
0334    xRooNode Replace(const xRooNode &node); // use to replace a node in the tree at the location of this node
0335    xRooNode Remove(const xRooNode &child);
0336    xRooNode
0337    Add(const xRooNode &child,
0338        Option_t *opt =
0339           ""); // = components()[child.GetName()]=child; although need to handle case of adding same term multiple times
0340    xRooNode Multiply(const xRooNode &child, Option_t *opt = ""); // = factors()[child.GetName()]=child;
0341    xRooNode Vary(const xRooNode &child);
0342    xRooNode Constrain(const xRooNode &child);
0343 
0344    xRooNode Combine(const xRooNode &rhs, bool silent = false); // combine rhs with this node
0345 
0346    xRooNode reduced(const std::string &range = "", bool invert = false)
0347       const; // return a node representing reduced version of this node, will use the SetRange to reduce if blank
0348    xRooNode reduced(const std::function<bool(const xRooNode &)> selector) const;
0349 
0350    // following versions are for the menu in the GUI
0351    /** @private */
0352    void _Add_(const char *name, const char *opt); // *MENU*
0353    /** @private */
0354    xRooNode _Multiply_(const char *what) { return Multiply(what); } // *MENU*
0355    /** @private */
0356    void _Vary_(const char *what); // *MENU*
0357    /** @private */
0358    xRooNode _Constrain_(const char *what) { return Constrain(what); } // *MENU*
0359    /** @private */
0360    void _ShowVars_(bool set = true); // *TOGGLE* *GETTER=_IsShowVars_
0361    /** @private */
0362    bool _IsShowVars_() const;
0363    /** @private */
0364    void _SetAttribute_(const char *name, const char *value = nullptr); // *MENU*
0365 
0366    void SetHidden(bool set = true); // *TOGGLE* *GETTER=IsHidden
0367    bool IsHidden() const;
0368 
0369    bool SetContents(const TObject &obj)
0370    {
0371       operator=(obj);
0372       return true;
0373    } // populates the node's comp (creating if necessary)  from given object
0374    bool SetData(const TObject &obj, const xRooNode &data = "obsData");
0375 
0376    bool SetContent(double value);                                     // uses a RooConst
0377    bool SetContent(double value, const char *par, double parVal = 1); // shortcut to setting a variation content
0378    bool SetContents(const TObject &obj, const char *par, double parVal)
0379    {
0380       variations()[TString::Format("%s=%g", par, parVal).Data()]->operator=(obj);
0381       return true;
0382    }
0383    bool SetBinError(int bin, double value);
0384    bool SetBinContent(int bin, double value, const char *par = nullptr, double parVal = 1);
0385    bool SetBinData(int bin, double value, const xRooNode &data = "obsData"); // only valid for pdf nodes
0386 
0387    /** @private */
0388    void _SetContent_(double value); // *MENU*
0389    /** @private */
0390    void _SetBinContent_(int bin, double value, const char *par = "", double parVal = 1); // *MENU*
0391 
0392    bool SetXaxis(const RooAbsBinning &binning);
0393    bool SetXaxis(TAxis *ax);
0394    bool SetXaxis(const char *name, const char *title, int nbins, double low, double high);
0395    bool SetXaxis(const char *name, const char *title, int nbins, const double *bins);
0396    bool SetXaxis(const char *title, int nbins, double low, double high)
0397    {
0398       return SetXaxis("xaxis", title, nbins, low, high);
0399    }
0400    bool SetXaxis(const char *title, int nbins, const double *bins) { return SetXaxis("xaxis", title, nbins, bins); }
0401    bool SetXaxis(int nbins, double low, double high) { return SetXaxis("xaxis", "", nbins, low, high); }
0402    bool SetXaxis(int nbins, const double *bins) { return SetXaxis("xaxis", "", nbins, bins); }
0403 
0404    std::shared_ptr<TStyle>
0405    style(TObject *initObject = nullptr, bool autoCreate = true) const; // DEPRECATED: TO BE REMOVED
0406    xRooNode styles(TObject *initObject = nullptr, bool autoCreate = true) const;
0407 
0408    TAxis *GetXaxis() const;
0409 
0410    double GetBinData(int bin, const xRooNode &data = "obsData");
0411    double GetBinContent(int bin) const { return GetBinContents(bin, bin).at(0); }
0412    std::vector<double> GetBinContents(int binStart = 1, int binEnd = 0) const; // default will get all bins
0413    double
0414    GetBinError(int bin, const xRooNode &fr = "", int nToys = 0, bool errorsHi = false, bool errorsLo = false) const;
0415    std::vector<double> GetBinErrors(int binStart = 1, int binEnd = 0, const xRooNode &fr = "", int nToys = 0,
0416                                     bool errorsHi = false, bool errorsLo = false) const;
0417    std::pair<double, double> IntegralAndError(const xRooNode &fr = "", const char *rangeName = nullptr, int nToys = 0,
0418                                               bool errorsHi = false, bool errorsLo = false) const;
0419 
0420    std::vector<double> GetBinErrorsHi(int binStart = 1, int binEnd = 0, const xRooNode &fr = "", int nToys = 0) const
0421    {
0422       return GetBinErrors(binStart, binEnd, fr, nToys, true, false);
0423    }
0424    std::vector<double> GetBinErrorsLo(int binStart = 1, int binEnd = 0, const xRooNode &fr = "", int nToys = 0) const
0425    {
0426       return GetBinErrors(binStart, binEnd, fr, nToys, false, true);
0427    }
0428    double GetBinErrorHi(int bin, const xRooNode &fr = "", int nToys = 0) const
0429    {
0430       return GetBinError(bin, fr, nToys, true, false);
0431    }
0432    double GetBinErrorLo(int bin, const xRooNode &fr = "", int nToys = 0) const
0433    {
0434       return GetBinError(bin, fr, nToys, false, true);
0435    }
0436 
0437    // methods to access default content and error
0438    double GetContent() const { return GetBinContent(fBinNumber); }
0439    double GetError(const xRooNode &fr = "", int nToys = 0, bool errorsHi = false, bool errorsLo = false) const
0440    {
0441       return (fBinNumber == -1) ? IntegralAndError(fr, "", nToys, errorsHi, errorsLo).second
0442                                 : GetBinError(fBinNumber, fr, nToys, errorsHi, errorsLo);
0443    }
0444    double GetErrorHi(const xRooNode &fr = "", int nToys = 0) const { return GetError(fr, nToys, true, false); }
0445    double GetErrorLo(const xRooNode &fr = "", int nToys = 0) const { return GetError(fr, nToys, false, true); }
0446    double GetData(const xRooNode &data = "obsData") { return GetBinData(fBinNumber, data); }
0447 
0448    // methods to access content and covariances of the CHILDREN of a node
0449    std::vector<double> contents() const;
0450    TMatrixDSym covariances(const xRooNode &fr = "") const;
0451    xRooNLLVar nll(const xRooNode &_data, std::initializer_list<RooCmdArg> nllOpts) const;
0452    xRooNLLVar nll(const xRooNode &_data, const RooLinkedList &nllOpts) const;
0453    xRooNLLVar nll(const xRooNode &_data = "") const; // uses xRooFit::createNLLOption for nllOpts
0454 
0455    xRooNLLVar
0456    nll(const char *_data,
0457        std::initializer_list<RooCmdArg> nllOpts = {}) const; // exists to have sensible exception reporting in python
0458                                                              // (rather than conversion errors, which are incorrect)
0459 
0460    xRooNode fitResult(const char *opt = "") const;      // todo: make this 'fitResults'
0461    void SetFitResult(const RooFitResult *fr = nullptr); // null means will load prefit
0462    void SetFitResult(const std::shared_ptr<const RooFitResult> &fr) { SetFitResult(fr.get()); }
0463    void SetFitResult(const xRooNode &fr);
0464 
0465    xRooNode
0466    generate(const xRooNode &fr = "", bool expected = false,
0467             int seed = 0); // generate a dataset from a pdf node using given fr - if none given will use current fit
0468 
0469    /** @private */
0470    void _fit_(const char *constParValues = "", const char *options = "GoF"); // *MENU*
0471    /** @private */
0472    void _generate_(const char *name = "", bool expected = false); // *MENU*
0473    /** @private */
0474    void _scan_(const char *what = "plr", double nToys = 0, const char *xvar = "", int nPointsX = 0, double lowX = 0,
0475                double highX = 0 /*, const char* yvar="", int nBinsY=0, double lowY=0, double highY=0*/,
0476                const char *constParValues = "", const char *options = ""); // *MENU*
0477    //    xRooNode fitTo(const char* datasetName) const;
0478    //    xRooNode fitTo(const xRooNode& _data) const;
0479    //    xRooNode generate(bool expected=false) const;
0480    //    void minosScan(const char* parName); // *MENU*
0481    //    void pllScan(const char* parName, int npoints=100); // *MENU*
0482    //    void breakdown(const char* parNames, const char* groupNames); // *MENU*
0483 
0484    /*
0485    double pll(Node2& data, const char* parName, double value, const Asymptotics::PLLType& pllType =
0486    Asymptotics::TwoSided) const;
0487    // pair is obs p_sb and p_b, vector is expected -2->+2 sigma p_sb (p_b are known by construction)
0488    std::pair<std::pair<double,double>,std::vector<double>>  pValue(Node2& data, const char* parName, double value,
0489    double alt_value, const Asymptotics::PLLType& pllType); double sigma_mu(Node2& data, const char* parName, double
0490    value, double alt_value) const;
0491 */
0492 
0493    void Checked(TObject *obj, bool val);
0494    void SetChecked(bool val = true) { Checked(this, val); }
0495 
0496    /** @private */
0497    xRooNode histo(const xRooNode &vars = "x", const xRooNode &fr = "", bool content = true, bool errors = true,
0498                   bool stack = true, bool errorsHi = false, bool errorsLo = false, int nErrorToys = 0) const;
0499    /** @private */
0500    xRooNode filter(const xRooNode &range) const;
0501 
0502    TGraph *BuildGraph(RooAbsLValue *v = nullptr, bool includeZeros = false, TVirtualPad *fromPad = nullptr) const;
0503    TH1 *BuildHistogram(RooAbsLValue *v = nullptr, bool empty = false, bool errors = false, int binStart = 1,
0504                        int binEnd = 0, const xRooNode &fr = "", bool errorsHi = false, bool errorsLo = false,
0505                        int nErrorToys = 0, TH1 *templateHist = nullptr, bool nostack = true,
0506                        bool setInterp = false) const;
0507    xRooNode mainChild() const;
0508    void Draw(Option_t *opt = "") override; // *MENU*
0509 
0510    void SaveAs(const char *filename = "", Option_t *option = "") const override; // *MENU*
0511 
0512    /** @private */
0513    TGListTreeItem *GetTreeItem(TBrowser *b) const;
0514    /** @private */
0515    TGListTree *GetListTree(TBrowser *b) const;
0516 
0517    static void Interactive_PLLPlot();
0518    static void Interactive_Pull();
0519    class InteractiveObject : public TQObject {
0520    public:
0521       void Interactive_PLLPlot(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y);
0522       ClassDefOverride(InteractiveObject, 0)
0523    };
0524    static InteractiveObject *gIntObj;
0525 
0526    mutable std::shared_ptr<TObject> fComp; ///<!
0527    int fTimes = 1;      // when the same comp appears multiple times in a parent node, this is increased to reflect that
0528    int fBinNumber = -1; // used by 'bin' nodes (a node that refers to a specific bin of a parent)
0529    std::shared_ptr<xRooNode> fParent; ///<!
0530    std::string fFolder;               // folder to put this node in when 'organising' the parent
0531 
0532    void SetRange(const char *range, double low = std::numeric_limits<double>::quiet_NaN(),
0533                  double high = std::numeric_limits<double>::quiet_NaN()); // *MENU*
0534    const char *GetRange() const;
0535    mutable std::string fRange; ///<! only here so can have char* GetRange return so can return nullptr for no range set
0536                                ///<! (required for RooCategory)
0537 
0538    mutable std::shared_ptr<TAxis>
0539       fXAxis; ///<! appears that if was fXaxis then dialog box for SetXaxis will take as current value
0540 
0541    mutable bool fInterrupted = false;
0542 
0543    bool fAcquirer = false; // if true, when acquiring will go into objects memory rather than pass onto parent
0544    std::shared_ptr<xRooNode> fProvider; ///<! like a parent but only for use by getObject
0545 
0546    std::shared_ptr<xRooNode> parentPdf() const; // find first parent that is a pdf
0547 
0548    /** @private */
0549    void sterilize() const;
0550 
0551    std::vector<std::shared_ptr<xRooNode>> fBrowsables;   // will appear in the browser tree but are not actual children
0552    std::function<xRooNode(xRooNode *)> fBrowseOperation; // a way to specify a custom browsing operation
0553 
0554    /** @private */
0555    std::shared_ptr<xRooNode> getBrowsable(const char *name) const;
0556 
0557    ClassDefOverride(xRooNode, 0)
0558 };
0559 
0560 END_XROOFIT_NAMESPACE
0561 
0562 
0563 namespace cling {
0564 std::string printValue(const XROOFIT_NAMESPACE_NAME::xRooNode *val);
0565 }
0566 
0567 #endif // include guard