Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-27 09:26:58

0001 /*****************************************************************************
0002  * Project: RooFit                                                           *
0003  * Package: RooFitCore                                                       *
0004  *    File: $Id: RooDataHist.h,v 1.37 2007/05/11 09:11:30 verkerke Exp $
0005  * Authors:                                                                  *
0006  *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
0007  *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
0008  *                                                                           *
0009  * Copyright (c) 2000-2005, Regents of the University of California          *
0010  *                          and Stanford University. All rights reserved.    *
0011  *                                                                           *
0012  * Redistribution and use in source and binary forms,                        *
0013  * with or without modification, are permitted according to the terms        *
0014  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
0015  *****************************************************************************/
0016 #ifndef ROO_DATA_HIST
0017 #define ROO_DATA_HIST
0018 
0019 #include <RooAbsData.h>
0020 #include <RooArgSet.h>
0021 #include <RooDirItem.h>
0022 #include <RooGlobalFunc.h>
0023 
0024 #include <Rtypes.h>
0025 
0026 #include <functional>
0027 #include <map>
0028 #include <memory>
0029 #include <string>
0030 #include <string_view>
0031 #include <unordered_map>
0032 #include <vector>
0033 
0034 class TAxis ;
0035 class RooAbsArg;
0036 class RooCategory ;
0037 class RooPlot;
0038 class RooAbsLValue ;
0039 
0040 class RooDataHist : public RooAbsData, public RooDirItem {
0041 public:
0042 
0043   // Constructors, factory methods etc.
0044   RooDataHist() ;
0045   RooDataHist(RooStringView name, RooStringView title, const RooArgSet& vars, const char* binningName=nullptr) ;
0046   RooDataHist(RooStringView name, RooStringView title, const RooArgSet& vars, const RooAbsData& data, double initWgt=1.0) ;
0047   RooDataHist(RooStringView name, RooStringView title, const RooArgList& vars, const TH1* hist, double initWgt=1.0) ;
0048   RooDataHist(RooStringView name, RooStringView title, const RooArgList& vars, RooCategory& indexCat, std::map<std::string,TH1*> histMap, double initWgt=1.0) ;
0049   RooDataHist(RooStringView name, RooStringView title, const RooArgList& vars, RooCategory& indexCat, std::map<std::string,RooDataHist*> dhistMap, double wgt=1.0) ;
0050   RooDataHist(RooStringView name, RooStringView title, const RooArgList& vars, const RooCmdArg& arg1, const RooCmdArg& arg2={}, const RooCmdArg& arg3={},
0051         const RooCmdArg& arg4={},const RooCmdArg& arg5={},const RooCmdArg& arg6={},const RooCmdArg& arg7={},const RooCmdArg& arg8={}) ;
0052 
0053   /// For internal use in RooFit.
0054   template<class Val_t>
0055   inline RooDataHist(RooStringView name, RooStringView title, const RooArgList& vars, RooCategory& indexCat, RooFit::Detail::FlatMap<std::string,Val_t> const& histMap, double initWgt=1.0)
0056     : RooDataHist(name, title, vars, indexCat, RooFit::Detail::flatMapToStdMap(histMap), initWgt) {}
0057 
0058   RooDataHist& operator=(const RooDataHist&) = delete;
0059 
0060   RooDataHist(const RooDataHist& other, const char* newname = nullptr) ;
0061   TObject* Clone(const char* newname="") const override {
0062     return new RooDataHist(*this, newname && newname[0] != '\0' ? newname : GetName());
0063   }
0064   ~RooDataHist() override ;
0065 
0066   /// Return empty clone of this RooDataHist.
0067   RooFit::OwningPtr<RooAbsData> emptyClone(const char* newName=nullptr, const char* newTitle=nullptr, const RooArgSet*vars=nullptr, const char* /*wgtVarName*/=nullptr) const override {
0068     return RooFit::makeOwningPtr(std::make_unique<RooDataHist>(newName?newName:GetName(),newTitle?newTitle:GetTitle(),vars?*vars:*get()));
0069   }
0070 
0071   /// Add `wgt` to the bin content enclosed by the coordinates passed in `row`.
0072   void add(const RooArgSet& row, double wgt=1.0) override { add(row,wgt,-1.); }
0073   void add(const RooArgSet& row, double weight, double sumw2);
0074   void set(std::size_t binNumber, double weight, double wgtErr);
0075   void set(const RooArgSet& row, double weight, double wgtErr=-1.) ;
0076   void set(const RooArgSet& row, double weight, double wgtErrLo, double wgtErrHi) ;
0077 
0078   void add(const RooAbsData& dset, const RooFormulaVar* cutVar=nullptr, double weight=1.0 ) ;
0079   void add(const RooAbsData& dset, const char* cut, double weight=1.0 ) ;
0080 
0081   /// Get bin centre of current bin.
0082   const RooArgSet* get() const override { return &_vars; }
0083   const RooArgSet* get(Int_t binNumber) const override;
0084   virtual const RooArgSet* get(const RooArgSet& coord) const;
0085   double sumEntries() const override;
0086   double sumEntries(const char* cutSpec, const char* cutRange=nullptr) const override;
0087 
0088   /// Always returns true as all histograms use event weights.
0089   bool isWeighted() const override { return true; }
0090   bool isNonPoissonWeighted() const override ;
0091 
0092   std::span<const double> getWeightBatch(std::size_t first, std::size_t len, bool sumW2=false) const override;
0093 
0094   /// Retrieve all bin volumes. Bins are indexed according to getIndex().
0095   std::span<const double> binVolumes(std::size_t first, std::size_t len) const {
0096     return {_binv + first, len};
0097   }
0098 
0099   double sum(bool correctForBinSize, bool inverseCorr=false) const ;
0100   double sum(const RooArgSet& sumSet, const RooArgSet& sliceSet, bool correctForBinSize, bool inverseCorr=false) ;
0101   double sum(const RooArgSet& sumSet,
0102                const RooArgSet& sliceSet,
0103                bool correctForBinSize,
0104                bool inverseCorr,
0105                const std::map<const RooAbsArg*, std::pair<double, double> >& ranges,
0106                std::function<double(int)> getBinScale = [](int){ return 1.0; } );
0107 
0108   void weights(double* output, std::span<double const> xVals, int intOrder, bool correctForBinSize, bool cdfBoundaries);
0109   /// Return weight of i-th bin. \see getIndex()
0110   double weight(std::size_t i) const { return _wgt[i]; }
0111   double weightFast(const RooArgSet& bin, int intOrder, bool correctForBinSize, bool cdfBoundaries);
0112   double weight(const RooArgSet& bin, Int_t intOrder=1, bool correctForBinSize=false, bool cdfBoundaries=false, bool oneSafe=false);
0113   /// Return squared weight sum of i-th bin. \see getIndex().
0114   /// If sumw2 is not
0115   /// being tracked, assume that all previous fill operations had a
0116   /// weight of 1, i.e., return the bare weight of the bin.
0117   double weightSquared(std::size_t i) const { return _sumw2 ? _sumw2[i] : _wgt[i]; }
0118   /// Return bin volume of i-th bin. \see getIndex()
0119   double binVolume(std::size_t i) const { return _binv[i]; }
0120   double binVolume(const RooArgSet& bin) const;
0121 
0122   TIterator* sliceIterator(RooAbsArg& sliceArg, const RooArgSet& otherArgs) ;
0123 
0124   void weightError(double& lo, double& hi, ErrorType etype=Poisson) const override;
0125   /// \copydoc RooAbsData::weightError(RooAbsData::ErrorType) const
0126   double weightError(ErrorType etype=Poisson) const override {
0127     // Return symmetric error on current bin calculated either from Poisson statistics or from SumOfWeights
0128     double lo;
0129     double hi;
0130     weightError(lo,hi,etype) ;
0131     return (lo+hi)/2 ;
0132   }
0133 
0134   RooPlot *plotOnImpl(RooPlot *frame, PlotOpt o) const override;
0135 
0136   void reset() override;
0137 
0138   void printMultiline(std::ostream& os, Int_t content, bool verbose=false, TString indent="") const override;
0139   void printArgs(std::ostream& os) const override;
0140   void printValue(std::ostream& os) const override;
0141   
0142   /// Print the contents of the dataset to the specified output stream.
0143   void printContents(std::ostream& os = std::cout) const override;
0144 
0145   void SetName(const char *name) override;
0146   void SetNameTitle(const char *name, const char* title) override;
0147 
0148   Int_t getIndex(const RooAbsCollection& coord, bool fast = false) const;
0149   /// \copydoc getIndex(const RooAbsCollection&,bool) const
0150   ///
0151   /// \note This overload only exists because there is an implicit conversion from RooAbsArg
0152   /// to RooArgSet, and this needs to remain supported. This enables code like
0153   /// ```
0154   /// RooRealVar x(...);
0155   /// dataHist.getIndex(x);
0156   /// ```
0157   /// It is, however, recommended to use
0158   /// ```
0159   /// dataHist.getIndex(RooArgSet(x));
0160   /// ```
0161   /// in this case.
0162   Int_t getIndex(const RooArgSet& coord, bool fast = false) const {
0163     return getIndex(static_cast<const RooAbsCollection&>(coord), fast);
0164   }
0165 
0166   void removeSelfFromDir() { removeFromDir(this) ; }
0167 
0168 
0169   ////////////////////////////////////////////////////////////////////////////////////////////////////////////
0170   /// @name Deprecated functions
0171   /// These functions rely on the fact that an event has been loaded before they are called. It is advised
0172   /// to switch to their counterparts that take bin numbers as arguments. In this way, code like,
0173   /// ```
0174   ///   const RooArgSet* coordinates = dataHist.get(i); // Need this to achieve side effect on next call of weight() - bad.
0175   ///   const double weight = dataHist.weight();
0176   ///   processEvent(coordinates, weight);
0177   /// ```
0178   /// becomes
0179   /// ```
0180   ///   processEvent(dataHist.get(i), dataHist.weight(i));
0181   /// ```
0182   /// The index of a set of coordinates can be computed using getIndex().
0183   /// @{
0184 
0185   /// Return weight of last bin that was requested with get().
0186   /// \deprecated Use the safer weight(std::size_t) const.
0187   double weight() const override
0188   R__SUGGEST_ALTERNATIVE("Use the safer weight(std::size_t) const.")
0189   { return  _wgt[_curIndex]; }
0190   /// Return squared weight of last bin that was requested with get().
0191   /// \deprecated Use the safer weightSquared(std::size_t) const.
0192   double weightSquared() const override
0193   R__SUGGEST_ALTERNATIVE("Use the safer weightSquared(std::size_t) const.")
0194   { return weightSquared(_curIndex); }
0195   /// Return volume of current bin. \deprecated Use binVolume(std::size_t) const.
0196   double binVolume() const
0197   R__SUGGEST_ALTERNATIVE("Use binVolume(std::size_t) const.")
0198   { return _binv[_curIndex]; }
0199   /// Write `weight` into current bin. \deprecated Use set(std::size_t,double,double)
0200   void set(double wgt, double wgtErr=-1)
0201   R__SUGGEST_ALTERNATIVE("Use set(std::size_t,double,double).");
0202 
0203   ///@}
0204   ////////////////////////////////////////////////////////////////////////////////////////////////////////////
0205 
0206   /// Structure to cache information on the histogram variable that is
0207   /// frequently used for histogram weights retrieval.
0208   struct VarInfo {
0209     size_t nRealVars = 0;
0210     size_t realVarIdx1 = 0;
0211     size_t realVarIdx2 = 0;
0212     bool initialized = false;
0213   };
0214 
0215   std::vector<std::unique_ptr<const RooAbsBinning>> const& getBinnings() const { return _lvbins; }
0216 
0217   int arraySize()   const { return _arrSize; }  
0218   double const* weightArray()   const { return _wgt; }
0219   double const* wgtErrLoArray() const { return _errLo; }
0220   double const* wgtErrHiArray() const { return _errHi; }
0221   double const* sumW2Array()    const { return _sumw2; }
0222 
0223   std::string calculateTreeIndexForCodeSquash(RooFit::Experimental::CodegenContext &ctx,
0224                                               const RooAbsCollection &coords, bool reverse = false) const;
0225   std::string declWeightArrayForCodeSquash(RooFit::Experimental::CodegenContext &ctx,
0226                                            bool correctForBinSize) const;
0227 
0228   protected:
0229   friend class RooDataHistSliceIter ;
0230 
0231   std::size_t calcTreeIndex(const RooAbsCollection& coords, bool fast) const;
0232   /// Legacy overload to calculate the tree index from the current value of `_vars`.
0233   /// \deprecated Use calcTreeIndex(const RooArgSet&,bool) const.
0234   Int_t calcTreeIndex() const { return static_cast<Int_t>(calcTreeIndex(_vars, true)); }
0235 
0236   void initialize(const char* binningName=nullptr,bool fillTree=true) ;
0237   std::unique_ptr<RooAbsData> reduceEng(const RooArgSet& varSubset, const RooFormulaVar* cutVar, const char* cutRange=nullptr,
0238                   std::size_t nStart=0, std::size_t nStop=std::numeric_limits<std::size_t>::max()) const override;
0239   double interpolateDim(int iDim, double xval, size_t centralIdx, int intOrder, bool correctForBinSize, bool cdfBoundaries) ;
0240   const std::vector<double>& calculatePartialBinVolume(const RooArgSet& dimSet) const ;
0241   void checkBinBounds() const;
0242 
0243   void adjustBinning(const RooArgList& vars, const TH1& href, Int_t* offset=nullptr) ;
0244   void importTH1(const RooArgList& vars, const TH1& histo, double initWgt, bool doDensityCorrection) ;
0245   void importTH1Set(const RooArgList& vars, RooCategory& indexCat, std::map<std::string,TH1*> hmap, double initWgt, bool doDensityCorrection) ;
0246   void importDHistSet(const RooArgList& vars, RooCategory& indexCat, std::map<std::string,RooDataHist*> dmap, double initWgt) ;
0247 
0248   Int_t _arrSize{0}; // Size of member arrays.
0249   std::vector<Int_t> _idxMult ; // Multiplier jump table for index calculation
0250 
0251   double*         _wgt  {nullptr}; ///<[_arrSize] Weight array
0252   mutable double* _errLo{nullptr}; ///<[_arrSize] Low-side error on weight array
0253   mutable double* _errHi{nullptr}; ///<[_arrSize] High-side error on weight array
0254   mutable double* _sumw2{nullptr}; ///<[_arrSize] Sum of weights^2
0255   double*         _binv {nullptr}; ///<[_arrSize] Bin volume array
0256 
0257   mutable ULong64_t _curIndex{std::numeric_limits<ULong64_t>::max()}; ///< Current index
0258 
0259   mutable std::unordered_map<int,std::vector<double>> _pbinvCache ; ///<! Cache for arrays of partial bin volumes
0260   std::vector<RooAbsLValue*> _lvvars ; ///<! List of observables casted as RooAbsLValue
0261   std::vector<std::unique_ptr<const RooAbsBinning>> _lvbins ; ///<! List of used binnings associated with lvalues
0262   mutable std::vector<std::vector<double> > _binbounds;     ///<! list of bin bounds per dimension
0263 
0264   enum CacheSumState_t{
0265 // clang++ <v20 (-Wshadow) complains about shadowing TSystem.h global enum EFpeMask. Let's silence warning:
0266 #if defined(__clang__) && __clang_major__ < 20
0267 #pragma clang diagnostic push
0268 #pragma clang diagnostic ignored "-Wshadow"
0269 #endif
0270       kInvalid = 0,
0271 #if defined(__clang__) && __clang_major__ < 20
0272 #pragma clang diagnostic pop
0273 #endif
0274      kNoBinCorrection = 1, kCorrectForBinSize = 2, kInverseBinCorr = 3};
0275   mutable Int_t _cache_sum_valid{kInvalid}; ///<! Is cache sum valid? Needs to be Int_t instead of CacheSumState_t for subclasses.
0276   mutable double _cache_sum{0.};          ///<! Cache for sum of entries ;
0277 
0278 private:
0279   void interpolateQuadratic(double* output, std::span<const double> xVals, bool correctForBinSize, bool cdfBoundaries);
0280   void interpolateLinear(double* output, std::span<const double> xVals, bool correctForBinSize, bool cdfBoundaries);
0281   double weightInterpolated(const RooArgSet& bin, int intOrder, bool correctForBinSize, bool cdfBoundaries);
0282 
0283   void _adjustBinning(RooRealVar &theirVar, const TAxis &axis, RooRealVar *ourVar, Int_t *offset);
0284   void registerWeightArraysToDataStore() const;
0285   void initializeAsymErrArrays() const;
0286   VarInfo const& getVarInfo();
0287 
0288   static std::unique_ptr<RooAbsDataStore>
0289   makeDefaultDataStore(RooStringView name, RooStringView title, RooArgSet const &vars);
0290 
0291   VarInfo _varInfo; ///<!
0292   std::vector<double> _interpolationBuffer; ///<! Buffer to contain values used for weight interpolation
0293 
0294   ClassDefOverride(RooDataHist, 8) // Binned data set
0295 };
0296 
0297 #endif