Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:27

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_XROONLLVAR_H) || defined(XROOFIT_USE_PRAGMA_ONCE)
0019 #ifndef XROOFIT_USE_PRAGMA_ONCE
0020 #define XROOFIT_XROONLLVAR_H
0021 #endif
0022 
0023 #include "xRooFit.h"
0024 
0025 #include <RooFitResult.h>
0026 #include <RooLinkedList.h>
0027 
0028 #include <Fit/FitConfig.h>
0029 #include <Math/IOptions.h>
0030 #include <TAttFill.h>
0031 #include <TAttLine.h>
0032 #include <TAttMarker.h>
0033 
0034 #include <map>
0035 #include <set>
0036 
0037 class RooAbsReal;
0038 class RooAbsPdf;
0039 class RooAbsData;
0040 class RooAbsCollection;
0041 class RooNLLVar;
0042 class RooConstraintSum;
0043 class RooRealVar;
0044 class RooCmdArg;
0045 
0046 class TGraph;
0047 class TGraphErrors;
0048 class TMultiGraph;
0049 
0050 namespace RooStats {
0051 class HypoTestResult;
0052 class HypoTestInverterResult;
0053 } // namespace RooStats
0054 
0055 BEGIN_XROOFIT_NAMESPACE
0056 
0057 class xRooNode;
0058 
0059 class xRooNLLVar : public std::shared_ptr<RooAbsReal> {
0060 
0061 public:
0062    struct xValueWithError : public std::pair<double, double> {
0063       xValueWithError(const std::pair<double, double> &in = {0, 0}) : std::pair<double, double>(in) {}
0064       double value() const { return std::pair<double, double>::first; }
0065       double error() const { return std::pair<double, double>::second; }
0066    };
0067 
0068    void Print(Option_t *opt = "");
0069 
0070    xRooNLLVar(RooAbsPdf &pdf, const std::pair<RooAbsData *, const RooAbsCollection *> &data,
0071               const RooLinkedList &nllOpts = RooLinkedList());
0072    xRooNLLVar(const std::shared_ptr<RooAbsPdf> &pdf, const std::shared_ptr<RooAbsData> &data,
0073               const RooLinkedList &opts = RooLinkedList());
0074    xRooNLLVar(const std::shared_ptr<RooAbsPdf> &pdf,
0075               const std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>> &data,
0076               const RooLinkedList &opts = RooLinkedList());
0077 
0078    ~xRooNLLVar();
0079 
0080    // whenever implicitly converted to a RooAbsReal we will make sure our globs are set
0081    RooAbsReal *get() const { return func().get(); }
0082    RooAbsReal *operator->() const { return get(); }
0083 
0084    void reinitialize();
0085 
0086    void AddOption(const RooCmdArg &opt);
0087 
0088    std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>>
0089    getData() const; // returns pointer to data and snapshot of globs
0090    std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>>
0091    generate(bool expected = false, int seed = 0);
0092    // std::shared_ptr<const RooFitResult> snapshot();
0093 
0094    class xRooFitResult : public std::shared_ptr<const RooFitResult> {
0095    public:
0096       xRooFitResult(const std::shared_ptr<xRooNode> &in,
0097                     const std::shared_ptr<xRooNLLVar> &nll = nullptr); // : fNode(in) { }
0098       const RooFitResult *operator->() const;
0099       //        operator std::shared_ptr<const RooFitResult>() const;
0100       operator const RooFitResult *() const;
0101       void Draw(Option_t *opt = "");
0102 
0103       std::shared_ptr<xRooNLLVar> nll() const { return fNll; }
0104 
0105       RooArgList poi()
0106       {
0107          return get()
0108                    ? RooArgList(*std::unique_ptr<RooAbsCollection>(get()->floatParsFinal().selectByAttrib("poi", true)))
0109                    : RooArgList();
0110       }
0111 
0112       // generate a conditional fit using the given poi set to the given values
0113       // alias is used to store the fit result in the map under a different name
0114       xRooFitResult cfit(const char *poiValues, const char *alias = nullptr);
0115       // generate the conditional fit required for an impact calculation
0116       xRooFitResult ifit(const char *np, bool up, bool prefit = false);
0117       // calculate the impact on poi due to np. if approx is true, will use the covariance approximation instead
0118       double impact(const char *poi, const char *np, bool up = true, bool prefit = false, bool approx = false);
0119       double impact(const char *np, bool up = true, bool prefit = false, bool approx = false)
0120       {
0121          auto _poi = poi();
0122          if (_poi.size() != 1)
0123             throw std::runtime_error("xRooFitResult::impact: not one POI");
0124          return impact(poi().contentsString().c_str(), np, up, prefit, approx);
0125       }
0126 
0127       // calculate error on poi conditional on the given NPs being held constant at their post-fit values
0128       // The conditional error is often presented as the difference in quadrature to the total error i.e.
0129       // error contribution due to conditional NPs = sqrt( pow(totError,2) - pow(condError,2) )
0130       double conditionalError(const char *poi, const char *nps, bool up = true, bool approx = false);
0131 
0132       // rank all the np based on impact ... will use the covariance approximation if full impact not available
0133       // the approxThreshold sets the level below which the approximation will be returned
0134       // e.g. set it to 0 to not do approximation
0135       RooArgList ranknp(const char *poi, bool up = true, bool prefit = false,
0136                         double approxThreshold = std::numeric_limits<double>::infinity());
0137       // version that assumes only one parameter is poi
0138       RooArgList
0139       ranknp(bool up = true, bool prefit = false, double approxThreshold = std::numeric_limits<double>::infinity())
0140       {
0141          auto _poi = poi();
0142          if (_poi.size() != 1)
0143             throw std::runtime_error("xRooFitResult::ranknp: not one POI");
0144          return ranknp(poi().contentsString().c_str(), up, prefit, approxThreshold);
0145       }
0146 
0147       std::shared_ptr<xRooNode> fNode;
0148       std::shared_ptr<xRooNLLVar> fNll;
0149 
0150       std::shared_ptr<std::map<std::string, xRooFitResult>> fCfits;
0151    };
0152 
0153    xRooFitResult minimize(const std::shared_ptr<ROOT::Fit::FitConfig> & = nullptr);
0154 
0155    void SetFitConfig(const std::shared_ptr<ROOT::Fit::FitConfig> &in) { fFitConfig = in; }
0156    std::shared_ptr<ROOT::Fit::FitConfig> fitConfig(); // returns fit config, or creates a default one if not existing
0157    ROOT::Math::IOptions *fitConfigOptions(); // return pointer to non-const version of the options inside the fit config
0158 
0159    class xRooHypoPoint : public TNamed {
0160    public:
0161       xRooHypoPoint(std::shared_ptr<RooStats::HypoTestResult> htr = nullptr, const RooAbsCollection *_coords = nullptr);
0162       static std::set<int> allowedStatusCodes;
0163       void Print(Option_t *opt = "") const override;
0164       void Draw(Option_t *opt = "") override;
0165 
0166       // status bitmask of the available fit results
0167       // 0 = all ok
0168       int status() const;
0169 
0170       xValueWithError pll(bool readOnly = false);      // observed test statistic value
0171       xValueWithError sigma_mu(bool readOnly = false); // estimate of sigma_mu parameter
0172       std::shared_ptr<const RooFitResult> ufit(bool readOnly = false);
0173       std::shared_ptr<const RooFitResult> cfit_null(bool readOnly = false);
0174       std::shared_ptr<const RooFitResult> cfit_alt(bool readOnly = false);
0175       std::shared_ptr<const RooFitResult> cfit_lbound(bool readOnly = false); // cfit @ the lower bound of mu
0176       std::shared_ptr<const RooFitResult> gfit() { return fGenFit; }          // non-zero if data was generated
0177 
0178       std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>> fData;
0179       std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>> data();
0180 
0181       xValueWithError getVal(const char *what);
0182 
0183       // leave nSigma=NaN for observed p-value
0184       xValueWithError pNull_asymp(double nSigma = std::numeric_limits<double>::quiet_NaN());
0185       xValueWithError pAlt_asymp(double nSigma = std::numeric_limits<double>::quiet_NaN());
0186       xValueWithError pCLs_asymp(double nSigma = std::numeric_limits<double>::quiet_NaN());
0187       xValueWithError ts_asymp(double nSigma = std::numeric_limits<double>::quiet_NaN()); // test statistic value
0188 
0189       xValueWithError pNull_toys(double nSigma = std::numeric_limits<double>::quiet_NaN());
0190       xValueWithError pAlt_toys(double nSigma = std::numeric_limits<double>::quiet_NaN());
0191       xValueWithError pCLs_toys(double nSigma = std::numeric_limits<double>::quiet_NaN())
0192       {
0193          if (fNullVal() == fAltVal())
0194             return std::pair<double, double>(1, 0); // by construction
0195          auto null = pNull_toys(nSigma);
0196          auto alt = pAlt_toys(nSigma);
0197          double nom = (null.first == 0) ? 0 : null.first / alt.first;
0198          // double up = (null.first + null.second == 0) ? 0 : ((alt.first-alt.second<=0) ?
0199          // std::numeric_limits<double>::infinity() : (null.first + null.second)/(alt.first - alt.second)); double down
0200          // = (null.first - null.second == 0) ? 0 : (null.first - null.second)/(alt.first + alt.second);
0201          //  old way ... now doing like in pCLs_asymp by calculating the two variations ... but this is pessimistic
0202          //  assumes p-values are anticorrelated!
0203          //  so reverting to old
0204          return std::pair<double, double>(nom, (alt.first - alt.second <= 0)
0205                                                   ? std::numeric_limits<double>::infinity()
0206                                                   : (sqrt(pow(null.second, 2) + pow(alt.second * nom, 2)) / alt.first));
0207          // return std::pair(nom,std::max(std::abs(up - nom), std::abs(down - nom)));
0208       }
0209       xValueWithError ts_toys(double nSigma = std::numeric_limits<double>::quiet_NaN()); // test statistic value
0210 
0211       // Create a HypoTestResult representing the current state of this hypoPoint
0212       RooStats::HypoTestResult result();
0213 
0214       xRooHypoPoint generateNull(int seed = 0);
0215       xRooHypoPoint generateAlt(int seed = 0);
0216 
0217       void
0218       addNullToys(int nToys = 1, int seed = 0, double target = std::numeric_limits<double>::quiet_NaN(),
0219                   double target_nSigma = std::numeric_limits<double>::quiet_NaN()); // if seed=0 will use a random seed
0220       void
0221       addAltToys(int nToys = 1, int seed = 0, double target = std::numeric_limits<double>::quiet_NaN(),
0222                  double target_nSigma = std::numeric_limits<double>::quiet_NaN()); // if seed=0 will use a random seed
0223       void
0224       addCLsToys(int nToys = 1, int seed = 0, double target = std::numeric_limits<double>::quiet_NaN(),
0225                  double target_nSigma = std::numeric_limits<double>::quiet_NaN()); // if seed=0 will use a random seed
0226 
0227       RooArgList poi() const;
0228       RooArgList alt_poi() const; // values of the poi in the alt hypothesis (will be nans if not defined)
0229       RooRealVar &mu_hat();       // throws exception if ufit not available
0230 
0231       std::shared_ptr<xRooHypoPoint>
0232       asimov(bool readOnly =
0233                 false); // a two-sided hypoPoint with the alt hypothesis asimov dataset (used in sigma_mu() calculation)
0234 
0235       // std::string fPOIName;
0236       const char *fPOIName();
0237       xRooFit::Asymptotics::PLLType fPllType = xRooFit::Asymptotics::Unknown;
0238       // double fNullVal=1; double fAltVal=0;
0239       double fNullVal();
0240       double fAltVal();
0241 
0242       std::shared_ptr<const RooAbsCollection> coords; // pars of the nll that will be held const alongside POI
0243 
0244       std::shared_ptr<const RooFitResult> fUfit, fNull_cfit, fAlt_cfit, fLbound_cfit;
0245       std::shared_ptr<const RooFitResult> fGenFit; // if the data was generated, this is the fit is was generated from
0246       bool isExpected = false;                     // if genFit, flag says is asimov or not
0247 
0248       std::shared_ptr<xRooHypoPoint>
0249          fAsimov; // same as this point but pllType is twosided and data is expected post alt-fit
0250 
0251       // first is seed, second is ts value, third is weight
0252       std::vector<std::tuple<int, double, double>> nullToys; // would have to save these vectors for specific: null_cfit
0253                                                              // (genPoint), ufit, poiName, pllType, nullVal
0254       std::vector<std::tuple<int, double, double>> altToys;
0255 
0256       std::shared_ptr<xRooNLLVar> nllVar = nullptr; // hypopoints get a copy
0257       std::shared_ptr<RooStats::HypoTestResult> hypoTestResult = nullptr;
0258       std::shared_ptr<const RooFitResult> retrieveFit(int type);
0259 
0260       TString tsTitle(bool inWords = false) const;
0261 
0262    private:
0263       xValueWithError pX_toys(bool alt, double nSigma = std::numeric_limits<double>::quiet_NaN());
0264       size_t addToys(bool alt, int nToys, int initialSeed = 0, double target = std::numeric_limits<double>::quiet_NaN(),
0265                      double target_nSigma = std::numeric_limits<double>::quiet_NaN(), bool targetCLs = false,
0266                      double relErrThreshold = 2., size_t maxToys = 10000);
0267    };
0268 
0269    // use alt_value = nan to skip the asimov calculations
0270    xRooHypoPoint hypoPoint(const char *parName, double value,
0271                            double alt_value = std::numeric_limits<double>::quiet_NaN(),
0272                            const xRooFit::Asymptotics::PLLType &pllType = xRooFit::Asymptotics::Unknown);
0273    // same as above but specify parNames and values in a string
0274    xRooHypoPoint hypoPoint(const char *parValues, double alt_value, const xRooFit::Asymptotics::PLLType &pllType);
0275    // this next method requires poi to be flagged in the model already (with "poi" attribute) .. must be exactly one
0276    xRooHypoPoint hypoPoint(double value, double alt_value = std::numeric_limits<double>::quiet_NaN(),
0277                            const xRooFit::Asymptotics::PLLType &pllType = xRooFit::Asymptotics::Unknown);
0278 
0279    class xRooHypoSpace : public TNamed,
0280                          public TAttFill,
0281                          public TAttMarker,
0282                          public TAttLine,
0283                          public std::vector<xRooHypoPoint> {
0284    public:
0285       friend class xRooNLLVar;
0286       xRooHypoSpace(const char *name = "", const char *title = "");
0287       xRooHypoSpace(const RooStats::HypoTestInverterResult *result);
0288 
0289       bool AddModel(const xRooNode &pdf, const char *validity = "");
0290 
0291       void LoadFits(const char *apath);
0292 
0293       // A points over given parameter, number of points between low and high
0294       int AddPoints(const char *parName, size_t nPoints, double low, double high);
0295 
0296       void Print(Option_t *opt = "") const override;
0297 
0298       void Draw(Option_t *opt = "") override;
0299 
0300       RooArgList poi();
0301       std::shared_ptr<RooArgSet> pars() const { return fPars; };
0302       RooArgList axes() const;
0303 
0304       xRooHypoPoint &AddPoint(double value);            // adds by using the first axis var
0305       xRooHypoPoint &AddPoint(const char *coords = ""); // adds a new point at given coords or returns existing
0306 
0307       xRooHypoPoint &point(size_t i) { return at(i); }
0308 
0309       // build a TGraphErrors of pValues over the existing points
0310       // opt should include any of the following:
0311       //  cls: do pCLs, otherwise do pNull
0312       //  expX: do expected, X sigma (use +X or -X for contour, otherwise will return band unless X=0)
0313       //  toys: pvalues from available toys
0314       //  readonly: don't compute anything, just return available values
0315       std::shared_ptr<TGraphErrors> graph(const char *opt) const;
0316 
0317       // return a TMultiGraph containing the set of graphs for a particular visualization
0318       std::shared_ptr<TMultiGraph> graphs(const char *opt);
0319 
0320       // will evaluate more points until limit is below given relative uncert
0321       xValueWithError findlimit(const char *opt, double relUncert = std::numeric_limits<double>::infinity(),
0322                                 unsigned int maxTries = 20);
0323 
0324       // get currently available limit, with error. Use nSigma = nan for observed limit
0325       xValueWithError limit(const char *type = "cls", double nSigma = std::numeric_limits<double>::quiet_NaN()) const;
0326       int scan(const char *type, size_t nPoints, double low = std::numeric_limits<double>::quiet_NaN(),
0327                double high = std::numeric_limits<double>::quiet_NaN(),
0328                const std::vector<double> &nSigmas = {0, 1, 2, -1, -2, std::numeric_limits<double>::quiet_NaN()},
0329                double relUncert = 0.1);
0330       int scan(const char *type = "cls",
0331                const std::vector<double> &nSigmas = {0, 1, 2, -1, -2, std::numeric_limits<double>::quiet_NaN()},
0332                double relUncert = 0.1)
0333       {
0334          return scan(type, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(),
0335                      nSigmas, relUncert);
0336       }
0337       int scan(const char *type, double nSigma, double relUncert = 0.1)
0338       {
0339          return scan(type, std::vector<double>{nSigma}, relUncert);
0340       }
0341 
0342       // key is nSigma or "obs" for observed
0343       // will only do obs if "obs" dataset is not a generated dataset
0344       std::map<std::string, xValueWithError>
0345       limits(const char *opt = "cls",
0346              const std::vector<double> &nSigmas = {0, 1, 2, -1, -2, std::numeric_limits<double>::quiet_NaN()},
0347              double relUncert = std::numeric_limits<double>::infinity());
0348 
0349       std::shared_ptr<xRooNode> pdf(const RooAbsCollection &parValues) const;
0350       std::shared_ptr<xRooNode> pdf(const char *parValues = "") const;
0351 
0352       // caller needs to take ownership of the returned object
0353       RooStats::HypoTestInverterResult *result();
0354 
0355    private:
0356       // estimates where corresponding pValues graph becomes equal to 0.05
0357       // linearly interpolates log(pVal) when obtaining limits.
0358       // returns value and error
0359       static xValueWithError GetLimit(const TGraph &pValues, double target = std::numeric_limits<double>::quiet_NaN());
0360 
0361       static RooArgList toArgs(const char *str);
0362 
0363       xRooFit::Asymptotics::PLLType fTestStatType = xRooFit::Asymptotics::Unknown;
0364       std::shared_ptr<RooArgSet> fPars;
0365 
0366       std::map<std::shared_ptr<xRooNode>, std::shared_ptr<xRooNLLVar>> fNlls; // existing NLL functions of added pdfs;
0367 
0368       std::set<std::pair<std::shared_ptr<RooArgList>, std::shared_ptr<xRooNode>>> fPdfs;
0369    };
0370 
0371    xRooHypoSpace hypoSpace(const char *parName, int nPoints, double low, double high,
0372                            double alt_value = std::numeric_limits<double>::quiet_NaN(),
0373                            const xRooFit::Asymptotics::PLLType &pllType = xRooFit::Asymptotics::Unknown);
0374    xRooHypoSpace hypoSpace(const char *parName = "",
0375                            const xRooFit::Asymptotics::PLLType &pllType = xRooFit::Asymptotics::Unknown,
0376                            double alt_value = std::numeric_limits<double>::quiet_NaN());
0377    xRooHypoSpace hypoSpace(int nPoints, double low, double high,
0378                            double alt_value = std::numeric_limits<double>::quiet_NaN(),
0379                            const xRooFit::Asymptotics::PLLType &pllType = xRooFit::Asymptotics::Unknown);
0380    xRooHypoSpace hypoSpace(const char *parName, xRooFit::TestStatistic::Type tsType, int nPoints = 0)
0381    {
0382       return hypoSpace(parName, int(tsType), nPoints, -std::numeric_limits<double>::infinity(),
0383                        std::numeric_limits<double>::infinity());
0384    }
0385 
0386    std::shared_ptr<RooArgSet> pars(bool stripGlobalObs = true) const;
0387 
0388    void Draw(Option_t *opt = "");
0389 
0390    TObject *Scan(const RooArgList &scanPars, const std::vector<std::vector<double>> &coords,
0391                  const RooArgList &profilePars = RooArgList());
0392    TObject *Scan(const char *scanPars, const std::vector<std::vector<double>> &coords,
0393                  const RooArgList &profilePars = RooArgList());
0394    TObject *Scan(const char *scanPars, size_t nPoints, double low, double high, size_t nPointsY, double ylow,
0395                  double yhigh, const RooArgList &profilePars = RooArgList())
0396    {
0397       std::vector<std::vector<double>> coords;
0398       if (nPoints) {
0399          double step = (high - low) / (nPoints);
0400          for (size_t i = 0; i < nPoints; i++) {
0401             std::vector<double> coord({low + step * i});
0402             if (nPointsY) {
0403                double stepy = (yhigh - ylow) / (nPointsY);
0404                for (size_t j = 0; j < nPointsY; j++) {
0405                   coord.push_back({ylow + stepy * j});
0406                   coords.push_back(coord);
0407                   coord.resize(1);
0408                }
0409             } else {
0410                coords.push_back(coord);
0411             }
0412          }
0413       }
0414       return Scan(scanPars, coords, profilePars);
0415    }
0416    TObject *
0417    Scan(const char *scanPars, size_t nPoints, double low, double high, const RooArgList &profilePars = RooArgList())
0418    {
0419       return Scan(scanPars, nPoints, low, high, 0, 0, 0, profilePars);
0420    }
0421 
0422    std::shared_ptr<RooAbsReal> func() const; // will assign globs when called
0423    std::shared_ptr<RooAbsPdf> pdf() const { return fPdf; }
0424    RooAbsData *data() const; // returns the data hidden inside the NLLVar if there is some
0425    const RooAbsCollection *globs() const { return fGlobs.get(); }
0426 
0427    // NLL = mainTerm + constraintTerm
0428    // mainTerm = sum( entryVals ) + extendedTerm + simTerm [+ binnedDataTerm if activated binnedL option]
0429    // this is what it should be, at least
0430 
0431    // total nll should be all these values + constraint term + extended term + simTerm [+binnedDataTerm if activated
0432    // binnedL option]
0433    RooNLLVar *mainTerm() const;
0434    RooConstraintSum *constraintTerm() const;
0435 
0436    double getEntryVal(size_t entry) const; // get the Nll value for a specific entry
0437    double extendedTerm() const;
0438    double simTerm() const;
0439    double binnedDataTerm() const;
0440    double getEntryBinWidth(size_t entry) const;
0441 
0442    double ndof() const;
0443    double saturatedVal() const;
0444    double saturatedConstraintTerm() const;
0445    double saturatedMainTerm() const;
0446    double pgof() const; // a goodness-of-fit pvalue based on profile likelihood of a saturated model
0447    double mainTermPgof() const;
0448    double mainTermNdof() const;
0449 
0450    std::set<std::string> binnedChannels() const;
0451 
0452    // change the dataset - will check globs are the same
0453    bool setData(const std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>> &_data);
0454    bool setData(const std::shared_ptr<RooAbsData> &data, const std::shared_ptr<const RooAbsCollection> &globs)
0455    {
0456       return setData(std::make_pair(data, globs));
0457    }
0458    bool setData(const xRooNode &data);
0459 
0460    // using shared ptrs everywhere, even for RooLinkedList which needs custom deleter to clear itself
0461    // but still work ok for assignment operations
0462    std::shared_ptr<RooAbsPdf> fPdf;
0463    std::shared_ptr<RooAbsData> fData;
0464    std::shared_ptr<const RooAbsCollection> fGlobs;
0465 
0466    std::shared_ptr<RooLinkedList> fOpts;
0467    std::shared_ptr<ROOT::Fit::FitConfig> fFitConfig;
0468 
0469    std::shared_ptr<RooAbsCollection> fFuncVars;
0470    std::shared_ptr<RooAbsCollection> fConstVars;
0471    std::shared_ptr<RooAbsCollection> fFuncGlobs;
0472    std::string fFuncCreationLog; // messaging from when function was last created -- to save from printing to screen
0473 
0474    bool kReuseNLL = true;
0475 };
0476 
0477 namespace cling {
0478 std::string printValue(const xRooNLLVar::xValueWithError *val);
0479 std::string printValue(const std::map<std::string, xRooNLLVar::xValueWithError> *m);
0480 } // namespace cling
0481 
0482 END_XROOFIT_NAMESPACE
0483 
0484 #endif // include guard