Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:29:45

0001 // @(#)root/roostats:$Id$
0002 // Authors: Kevin Belasco        17/06/2009
0003 // Authors: Kyle Cranmer         17/06/2009
0004 /*************************************************************************
0005  * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 
0012 #ifndef ROOSTATS_MCMCCalculator
0013 #define ROOSTATS_MCMCCalculator
0014 
0015 #include "Rtypes.h"
0016 
0017 #include "TNamed.h"
0018 #include "RooAbsPdf.h"
0019 #include "RooAbsData.h"
0020 #include "RooArgSet.h"
0021 #include "RooArgList.h"
0022 #include "RooStats/ProposalFunction.h"
0023 #include "RooStats/IntervalCalculator.h"
0024 #include "RooStats/MCMCInterval.h"
0025 
0026 
0027 namespace RooStats {
0028 
0029    class ModelConfig;
0030 
0031    class MCMCCalculator : public IntervalCalculator, public TNamed {
0032 
0033    public:
0034       /// default constructor
0035       MCMCCalculator();
0036 
0037       /// Constructor for automatic configuration with basic settings and a
0038       /// ModelConfig.  Uses a UniformProposal, 10,000 iterations, 40 burn in
0039       /// steps, 50 bins for each RooRealVar, determines interval by histogram,
0040       /// and finds a 95% confidence interval.  Any of these basic settings can
0041       /// be overridden by calling one of the Set...() methods.
0042       MCMCCalculator(RooAbsData& data, const ModelConfig& model);
0043 
0044       /// Main interface to get a ConfInterval
0045       MCMCInterval* GetInterval() const override;
0046 
0047       /// Get the size of the test (eg. rate of Type I error)
0048       double Size() const override {return fSize;}
0049       /// Get the Confidence level for the test
0050       double ConfidenceLevel() const override {return 1.-fSize;}
0051 
0052       void SetModel(const ModelConfig & model) override;
0053 
0054       /// Set the DataSet if not already there
0055       void SetData(RooAbsData& data) override { fData = &data; }
0056 
0057       /// Set the Pdf if not already there
0058       virtual void SetPdf(RooAbsPdf& pdf) { fPdf = &pdf; }
0059 
0060       /// Set the Prior Pdf if not already there
0061       virtual void SetPriorPdf(RooAbsPdf& pdf) { fPriorPdf = &pdf; }
0062 
0063       /// specify the parameters of interest in the interval
0064       virtual void SetParameters(const RooArgSet& set) { fPOI.removeAll(); fPOI.add(set); }
0065 
0066       /// specify the parameters to store in the Markov chain
0067       /// By default all the parameters are stored
0068       virtual void SetChainParameters(const RooArgSet & set) { fChainParams.removeAll(); fChainParams.add(set); }
0069 
0070       /// specify the nuisance parameters (eg. the rest of the parameters)
0071       virtual void SetNuisanceParameters(const RooArgSet& set) {fNuisParams.removeAll(); fNuisParams.add(set);}
0072 
0073       /// set the conditional observables which will be used when creating the NLL
0074       /// so the pdf's will not be normalized on the conditional observables when computing the NLL
0075       virtual void SetConditionalObservables(const RooArgSet& set) {fConditionalObs.removeAll(); fConditionalObs.add(set);}
0076 
0077       /// set the global observables which will be used when creating the NLL
0078       /// so the constraint pdf's will be normalized correctly on the global observables when computing the NLL
0079       virtual void SetGlobalObservables(const RooArgSet& set) {fGlobalObs.removeAll(); fGlobalObs.add(set);}
0080 
0081       /// set the size of the test (rate of Type I error) ( Eg. 0.05 for a 95% Confidence Interval)
0082       void SetTestSize(double size) override {fSize = size;}
0083 
0084       /// set the confidence level for the interval (eg. 0.95 for a 95% Confidence Interval)
0085       void SetConfidenceLevel(double cl) override {fSize = 1.-cl;}
0086 
0087       /// set the proposal function for suggesting new points for the MCMC
0088       virtual void SetProposalFunction(ProposalFunction& proposalFunction)
0089       { fPropFunc = &proposalFunction; }
0090 
0091       /// set the number of iterations to run the metropolis algorithm
0092       virtual void SetNumIters(Int_t numIters)
0093       { fNumIters = numIters; }
0094 
0095       /// set the number of steps in the chain to discard as burn-in,
0096       /// starting from the first
0097       virtual void SetNumBurnInSteps(Int_t numBurnInSteps)
0098       { fNumBurnInSteps = numBurnInSteps; }
0099 
0100       /// set the number of bins to create for each axis when constructing the interval
0101       virtual void SetNumBins(Int_t numBins) { fNumBins = numBins; }
0102       /// set which variables to put on each axis
0103       virtual void SetAxes(RooArgList& axes)
0104       { fAxes = &axes; }
0105       /// set whether to use kernel estimation to determine the interval
0106       virtual void SetUseKeys(bool useKeys) { fUseKeys = useKeys; }
0107       /// set whether to use sparse histogram (if using histogram at all)
0108       virtual void SetUseSparseHist(bool useSparseHist)
0109       { fUseSparseHist = useSparseHist; }
0110 
0111       /// set what type of interval to have the MCMCInterval represent
0112       virtual void SetIntervalType(enum MCMCInterval::IntervalType intervalType)
0113       { fIntervalType = intervalType; }
0114 
0115       /// Set the left side tail fraction. This will automatically configure the
0116       /// MCMCInterval to find a tail-fraction interval.
0117       /// Note: that `a' must be in the range 0 <= a <= 1
0118       /// or the user will be notified of the error
0119       virtual void SetLeftSideTailFraction(double a);
0120 
0121       /// Set the desired level of confidence-level accuracy  for Keys interval
0122       /// determination.
0123       //
0124       /// When determining the cutoff PDF height that gives the
0125       /// desired confidence level (C_d), the algorithm will consider acceptable
0126       /// any found confidence level c such that Abs(c - C_d) < epsilon.
0127       ///
0128       /// Any value of this "epsilon" > 0 is considered acceptable, though it is
0129       /// advisable to not use a value too small, because the integration of the
0130       /// Keys PDF sometimes does not have extremely high accuracy.
0131       virtual void SetKeysConfidenceAccuracy(double epsilon)
0132       {
0133          if (epsilon < 0) {
0134             coutE(InputArguments) << "MCMCInterval::SetEpsilon will not allow "
0135                                   << "negative epsilon value" << std::endl;
0136          } else {
0137             fEpsilon = epsilon;
0138          }
0139       }
0140 
0141       /// When the shortest interval using Keys PDF could not be found to have
0142       /// the desired confidence level +/- the accuracy (see
0143       /// SetKeysConfidenceAccuracy()), the interval determination algorithm
0144       /// will have to terminate with an unsatisfactory confidence level when
0145       /// the bottom and top of the cutoff search range are very close to being
0146       /// equal.  This scenario comes into play when there seems to be an error
0147       /// in the accuracy of the Keys PDF integration, so the search range
0148       /// continues to shrink without converging to a cutoff value that will
0149       /// give an acceptable confidence level.  To choose how small to allow the
0150       /// search range to be before terminating, set the fraction delta such
0151       /// that the search will terminate when topCutoff (a) and bottomCutoff (b)
0152       /// satisfy this condition:
0153       ///
0154       /// std::abs(a - b) < std::abs(delta * (a + b)/2)
0155       virtual void SetKeysTerminationThreshold(double delta)
0156       {
0157          if (delta < 0.) {
0158             coutE(InputArguments) << "MCMCInterval::SetDelta will not allow "
0159                                   << "negative delta value" << std::endl;
0160          } else {
0161             fDelta = delta;
0162          }
0163       }
0164 
0165    protected:
0166       double fSize = -1;           ///< size of the test (eg. specified rate of Type I error)
0167       RooArgSet   fPOI;            ///< parameters of interest for interval
0168       RooArgSet   fNuisParams;     ///< nuisance parameters for interval (not really used)
0169       RooArgSet   fChainParams;    ///< parameters to store in the chain (if not specified they are all of them )
0170       RooArgSet   fConditionalObs; ///< conditional observables
0171       RooArgSet   fGlobalObs;      ///< global observables
0172       mutable ProposalFunction* fPropFunc; ///< Proposal function for MCMC integration
0173       RooAbsPdf * fPdf;      ///< pointer to common PDF (owned by the workspace)
0174       RooAbsPdf * fPriorPdf; ///< pointer to prior  PDF (owned by the workspace)
0175       RooAbsData * fData;    ///< pointer to the data (owned by the workspace)
0176       Int_t fNumIters = 0;   ///< number of iterations to run metropolis algorithm
0177       Int_t fNumBurnInSteps = 0; ///< number of iterations to discard as burn-in, starting from the first
0178       Int_t fNumBins = 0;        ///< set the number of bins to create for each
0179                                  ///< axis when constructing the interval
0180       RooArgList * fAxes;    ///< which variables to put on each axis
0181       bool fUseKeys = false; ///< whether to use kernel estimation to determine interval
0182       bool fUseSparseHist = false; ///< whether to use sparse histogram (if using hist at all)
0183       double fLeftSideTF = -1;     ///< left side tail-fraction for interval
0184       double fEpsilon = -1;        ///< acceptable error for Keys interval determination
0185 
0186       double fDelta = -1; ///< acceptable error for Keys cutoffs being equal
0187                           ///< topCutoff (a) considered == bottomCutoff (b) iff
0188                           ///< (std::abs(a - b) < std::abs(fDelta * (a + b)/2));
0189                           ///< Theoretically, the Abs is not needed here, but
0190                           ///< floating-point arithmetic does not always work
0191                           ///< perfectly, and the Abs doesn't hurt
0192       enum MCMCInterval::IntervalType fIntervalType = MCMCInterval::kShortest; // type of interval to find
0193 
0194       void SetupBasicUsage();
0195       void SetBins(const RooAbsCollection &coll, Int_t numBins) const
0196       {
0197          for (auto *r : dynamic_range_cast<RooRealVar *>(coll)){
0198             if (r) {
0199                r->setBins(numBins);
0200             }
0201          }
0202       }
0203 
0204       ClassDefOverride(MCMCCalculator,4) // Markov Chain Monte Carlo calculator for Bayesian credible intervals
0205    };
0206 }
0207 
0208 
0209 #endif