Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*
0002  * Project: RooFit
0003  * Authors:
0004  *   PB, Patrick Bos, Netherlands eScience Center, p.bos@esciencecenter.nl
0005  *
0006  * Copyright (c) 2021, 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 #ifndef ROOT_ROOFIT_TESTSTATISTICS_RooAbsL
0014 #define ROOT_ROOFIT_TESTSTATISTICS_RooAbsL
0015 
0016 #include "RooArgSet.h"
0017 #include "RooAbsArg.h" // enum ConstOpCode
0018 #include "RooAbsPdf.h"
0019 
0020 #include "Math/Util.h" // KahanSum
0021 
0022 #include <cstddef> // std::size_t
0023 #include <string>
0024 #include <memory>
0025 
0026 // forward declarations
0027 class RooAbsPdf;
0028 class RooAbsData;
0029 
0030 namespace RooFit {
0031 namespace TestStatistics {
0032 
0033 class RooAbsL {
0034 public:
0035    enum class Extended { Auto, Yes, No };
0036    static bool isExtendedHelper(RooAbsPdf *pdf, Extended extended);
0037 
0038    /// Convenience wrapper class used to distinguish between pdf/data owning and non-owning constructors.
0039    class ClonePdfData {
0040    public:
0041       ClonePdfData(RooAbsPdf *inPdf, RooAbsData *inData) : pdf{inPdf}, data{inData} {}
0042       ClonePdfData(std::unique_ptr<RooAbsPdf> inPdf, RooAbsData *inData)
0043          : pdf{inPdf.get()}, data{inData}, ownedPdf{std::move(inPdf)}
0044       {
0045       }
0046       RooAbsPdf *pdf = nullptr;
0047       RooAbsData *data = nullptr;
0048       std::shared_ptr<RooAbsPdf> ownedPdf;
0049    };
0050 
0051 private:
0052    RooAbsL(std::shared_ptr<RooAbsPdf> pdf, std::shared_ptr<RooAbsData> data, std::size_t N_events,
0053            std::size_t N_components, Extended extended);
0054 
0055 public:
0056    RooAbsL(RooAbsPdf *pdf, RooAbsData *data, std::size_t N_events, std::size_t N_components,
0057            Extended extended = Extended::Auto);
0058    RooAbsL(ClonePdfData in, std::size_t N_events, std::size_t N_components, Extended extended = Extended::Auto);
0059    RooAbsL(const RooAbsL &other);
0060    virtual ~RooAbsL() = default;
0061 
0062    void initClones(RooAbsPdf &inpdf, RooAbsData &indata);
0063 
0064    /// A part of some range delimited by two fractional points between 0 and 1 (inclusive).
0065    struct Section {
0066       Section(double begin, double end) : begin_fraction(begin), end_fraction(end)
0067       {
0068          if ((begin > end) || (begin < 0) || (end > 1)) {
0069             throw std::domain_error("Invalid input values for section; begin must be >= 0, end <= 1 and begin < end.");
0070          }
0071       }
0072 
0073       std::size_t begin(std::size_t N_total) const { return static_cast<std::size_t>(N_total * begin_fraction); }
0074 
0075       std::size_t end(std::size_t N_total) const
0076       {
0077          if (end_fraction == 1) {
0078             return N_total;
0079          } else {
0080             return static_cast<std::size_t>(N_total * end_fraction);
0081          }
0082       }
0083 
0084       friend bool operator==(const Section &lhs, const Section &rhs)
0085       {
0086          return lhs.begin_fraction == rhs.begin_fraction && lhs.end_fraction == rhs.end_fraction;
0087       }
0088 
0089       double begin_fraction;
0090       double end_fraction;
0091    };
0092 
0093    /*
0094     * \brief Evaluate (part of) the likelihood over a given range of events and components
0095     *
0096     * A fractional event range is used because components may have different numbers of events. For a
0097     * multi-component RooSumL, for instance, this means the caller need not indicate for each component which event
0098     * ranges they want to evaluate, but can just pass one overall fractional range.
0099     *
0100     * \param[in] events The fractional event range.
0101     * \param[in] components_begin The first component to be calculated.
0102     * \param[in] components_end The *exclusive* upper limit to the range of components to be calculated, i.e. the
0103     * component *before this one* is the last to be included. \return The value of part of the negative log likelihood,
0104     * returned as a KahanSum object which also includes a carry term.
0105     */
0106    virtual ROOT::Math::KahanSum<double>
0107    evaluatePartition(Section events, std::size_t components_begin, std::size_t components_end) = 0;
0108 
0109    // necessary from MinuitFcnGrad to reach likelihood properties:
0110    virtual std::unique_ptr<RooArgSet> getParameters();
0111 
0112    /// \brief Interface function signaling a request to perform constant term optimization.
0113    ///
0114    /// The default implementation takes no action other than to forward the calls to all servers. May be overridden in
0115    /// likelihood classes without a cached dataset, like RooSubsidiaryL.
0116    virtual void constOptimizeTestStatistic(RooAbsArg::ConstOpCode opcode, bool doAlsoTrackingOpt);
0117 
0118    virtual std::string GetName() const;
0119    virtual std::string GetTitle() const;
0120    virtual std::string GetInfo() const { return GetClassName() + "::" + pdf_->GetName(); }
0121    virtual std::string GetClassName() const = 0;
0122 
0123    // necessary in RooMinimizer (via LikelihoodWrapper)
0124    inline virtual double defaultErrorLevel() const { return 0.5; }
0125 
0126    // necessary in LikelihoodJob
0127    /// Number of dataset entries. Typically equal to the number of dataset events, except in RooSubsidiaryL, which has
0128    /// no events.
0129    virtual std::size_t numDataEntries() const;
0130    inline std::size_t getNEvents() const { return N_events_; }
0131    inline std::size_t getNComponents() const { return N_components_; }
0132    inline bool isExtended() const { return extended_; }
0133    inline void setSimCount(std::size_t value) { sim_count_ = value; }
0134 
0135 protected:
0136    // Note: pdf_ and data_ can be constructed in two ways, one of which implies ownership and the other does not.
0137    // Inspired by this: https://stackoverflow.com/a/61227865/1199693.
0138    // The owning variant is used for classes that need a pdf/data clone (RooBinnedL and RooUnbinnedL), whereas the
0139    // non-owning version is used for when a reference to the external pdf/dataset is good enough (RooSumL).
0140    // This means that pdf_ and data_ are not meant to actually be shared! If there were a unique_ptr with optional
0141    // ownership, we would have used that instead.
0142    std::shared_ptr<RooAbsPdf> pdf_;
0143    std::shared_ptr<RooAbsData> data_;
0144    std::unique_ptr<RooArgSet> normSet_; ///< Pointer to set with observables used for normalization
0145 
0146    std::size_t N_events_ = 1;
0147    std::size_t N_components_ = 1;
0148 
0149    bool extended_ = false;
0150 
0151    std::size_t sim_count_ = 1; // Total number of component p.d.f.s in RooSimultaneous (if any)
0152 };
0153 
0154 } // namespace TestStatistics
0155 } // namespace RooFit
0156 
0157 #endif // ROOT_ROOFIT_TESTSTATISTICS_RooAbsL