File indexing completed on 2025-01-18 10:10:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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 }
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
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;
0090 std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>>
0091 generate(bool expected = false, int seed = 0);
0092
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);
0098 const RooFitResult *operator->() const;
0099
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
0113
0114 xRooFitResult cfit(const char *poiValues, const char *alias = nullptr);
0115
0116 xRooFitResult ifit(const char *np, bool up, bool prefit = false);
0117
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
0128
0129
0130 double conditionalError(const char *poi, const char *nps, bool up = true, bool approx = false);
0131
0132
0133
0134
0135 RooArgList ranknp(const char *poi, bool up = true, bool prefit = false,
0136 double approxThreshold = std::numeric_limits<double>::infinity());
0137
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();
0157 ROOT::Math::IOptions *fitConfigOptions();
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
0167
0168 int status() const;
0169
0170 xValueWithError pll(bool readOnly = false);
0171 xValueWithError sigma_mu(bool readOnly = false);
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);
0176 std::shared_ptr<const RooFitResult> gfit() { return fGenFit; }
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
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());
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);
0195 auto null = pNull_toys(nSigma);
0196 auto alt = pAlt_toys(nSigma);
0197 double nom = (null.first == 0) ? 0 : null.first / alt.first;
0198
0199
0200
0201
0202
0203
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
0208 }
0209 xValueWithError ts_toys(double nSigma = std::numeric_limits<double>::quiet_NaN());
0210
0211
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());
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());
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());
0226
0227 RooArgList poi() const;
0228 RooArgList alt_poi() const;
0229 RooRealVar &mu_hat();
0230
0231 std::shared_ptr<xRooHypoPoint>
0232 asimov(bool readOnly =
0233 false);
0234
0235
0236 const char *fPOIName();
0237 xRooFit::Asymptotics::PLLType fPllType = xRooFit::Asymptotics::Unknown;
0238
0239 double fNullVal();
0240 double fAltVal();
0241
0242 std::shared_ptr<const RooAbsCollection> coords;
0243
0244 std::shared_ptr<const RooFitResult> fUfit, fNull_cfit, fAlt_cfit, fLbound_cfit;
0245 std::shared_ptr<const RooFitResult> fGenFit;
0246 bool isExpected = false;
0247
0248 std::shared_ptr<xRooHypoPoint>
0249 fAsimov;
0250
0251
0252 std::vector<std::tuple<int, double, double>> nullToys;
0253
0254 std::vector<std::tuple<int, double, double>> altToys;
0255
0256 std::shared_ptr<xRooNLLVar> nllVar = nullptr;
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
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
0274 xRooHypoPoint hypoPoint(const char *parValues, double alt_value, const xRooFit::Asymptotics::PLLType &pllType);
0275
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
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);
0305 xRooHypoPoint &AddPoint(const char *coords = "");
0306
0307 xRooHypoPoint &point(size_t i) { return at(i); }
0308
0309
0310
0311
0312
0313
0314
0315 std::shared_ptr<TGraphErrors> graph(const char *opt) const;
0316
0317
0318 std::shared_ptr<TMultiGraph> graphs(const char *opt);
0319
0320
0321 xValueWithError findlimit(const char *opt, double relUncert = std::numeric_limits<double>::infinity(),
0322 unsigned int maxTries = 20);
0323
0324
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
0343
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
0353 RooStats::HypoTestInverterResult *result();
0354
0355 private:
0356
0357
0358
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;
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;
0423 std::shared_ptr<RooAbsPdf> pdf() const { return fPdf; }
0424 RooAbsData *data() const;
0425 const RooAbsCollection *globs() const { return fGlobs.get(); }
0426
0427
0428
0429
0430
0431
0432
0433 RooNLLVar *mainTerm() const;
0434 RooConstraintSum *constraintTerm() const;
0435
0436 double getEntryVal(size_t entry) const;
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;
0447 double mainTermPgof() const;
0448 double mainTermNdof() const;
0449
0450 std::set<std::string> binnedChannels() const;
0451
0452
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
0461
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;
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 }
0481
0482 END_XROOFIT_NAMESPACE
0483
0484 #endif