Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:15:09

0001 /*****************************************************************************
0002  * Project: RooFit                                                           *
0003  * Package: RooFitCore                                                       *
0004  *    File: $Id$
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_CACHE_MANAGER
0017 #define ROO_CACHE_MANAGER
0018 
0019 #include "RooMsgService.h"
0020 #include "RooNormSetCache.h"
0021 #include "RooAbsReal.h"
0022 #include "RooArgSet.h"
0023 #include "RooArgList.h"
0024 #include "RooAbsCache.h"
0025 #include "RooAbsCacheElement.h"
0026 #include "RooNameReg.h"
0027 
0028 #include <ROOT/StringUtils.hxx>
0029 #include "Rtypes.h"
0030 
0031 #include <vector>
0032 
0033 /**
0034 \class RooCacheManager
0035 \ingroup Roofitcore
0036 
0037 Manages the storage of any type of data indexed on
0038 the choice of normalization and optionally the set of integrated observables.
0039 The purpose of this class is to facilitate storage of intermediate results
0040 in operator p.d.f.s whose value and inner working are often highly dependent
0041 on the user provided choice of normalization in getVal().
0042 
0043 For efficiency reasons these normalization set pointer are
0044 dereferenced as little as possible. This class contains a lookup
0045 table for RooArgSet pointer pairs -> normalization lists.  Distinct
0046 pointer pairs that represent the same normalization/projection are
0047 recognized and will all point to the same normalization list. Lists
0048 for up to 'maxSize' different normalization/ projection
0049 configurations can be cached.
0050 **/
0051 
0052 template<class T>
0053 class RooCacheManager : public RooAbsCache {
0054 
0055 public:
0056 
0057   RooCacheManager(Int_t maxSize=2) ;
0058   RooCacheManager(RooAbsArg* owner, Int_t maxSize=2) ;
0059   RooCacheManager(const RooCacheManager& other, RooAbsArg* owner=nullptr) ;
0060   ~RooCacheManager() override ;
0061 
0062   /// Getter function without integration set
0063   T* getObj(const RooArgSet* nset, Int_t* sterileIndex=nullptr, const TNamed* isetRangeName=nullptr) {
0064     return getObj(nset,nullptr,sterileIndex,isetRangeName) ;
0065   }
0066 
0067   /// Setter function without integration set
0068   Int_t setObj(const RooArgSet* nset, T* obj, const TNamed* isetRangeName=nullptr) {
0069     return setObj(nset,nullptr,obj,isetRangeName) ;
0070   }
0071 
0072   inline T* getObj(const RooArgSet* nset, const RooArgSet* iset, Int_t* sterileIdx, const char* isetRangeName)  {
0073     if (_wired) return _object[0] ;
0074     return getObj(nset,iset,sterileIdx,RooNameReg::ptr(isetRangeName)) ;
0075   }
0076 
0077   T* getObj(const RooArgSet* nset, const RooArgSet* iset, Int_t* sterileIndex=nullptr, const TNamed* isetRangeName=nullptr) ;
0078   Int_t setObj(const RooArgSet* nset, const RooArgSet* iset, T* obj, const TNamed* isetRangeName=nullptr) ;
0079 
0080   void reset() ;
0081   virtual void sterilize() ;
0082 
0083   /// Return index of slot used in last get or set operation
0084   Int_t lastIndex() const {
0085     return _lastIndex ;
0086   }
0087   /// Return size of cache
0088   Int_t cacheSize() const {
0089     return _size ;
0090   }
0091 
0092   /// Interface function to intercept server redirects
0093   bool redirectServersHook(const RooAbsCollection& /*newServerList*/, bool /*mustReplaceAll*/,
0094                  bool /*nameChange*/, bool /*isRecursive*/) override {
0095     return false ;
0096   }
0097   /// Interface function to intercept cache operation mode changes
0098   void operModeHook() override {
0099   }
0100   /// Interface function to cache add contents to output in tree printing mode
0101   void printCompactTreeHook(std::ostream&, const char *) override {
0102   }
0103 
0104   T* getObjByIndex(Int_t index) const ;
0105   RooArgSet selectFromSet1(RooArgSet const& argSet, int index) const ;
0106   RooArgSet selectFromSet2(RooArgSet const& argSet, int index) const ;
0107 
0108   /// Interface function to perform post-insert operations on cached object
0109   virtual void insertObjectHook(T&) {
0110   }
0111 
0112   void wireCache() override {
0113     if (_size==0) {
0114       oocoutI(_owner,Optimization) << "RooCacheManager::wireCache(" << _owner->GetName() << ") no cached elements!" << std::endl ;
0115     } else if (_size==1) {
0116       oocoutI(_owner,Optimization) << "RooCacheManager::wireCache(" << _owner->GetName() << ") now wiring cache" << std::endl ;
0117       _wired=true ;
0118     } else if (_size>1) {
0119       oocoutI(_owner,Optimization) << "RooCacheManager::wireCache(" << _owner->GetName() << ") cache cannot be wired because it contains more than one element" << std::endl ;
0120     }
0121   }
0122 
0123 protected:
0124 
0125   Int_t _maxSize ;       ///<! Maximum size
0126   Int_t _size = 0;       ///<! Actual use
0127   Int_t _lastIndex = -1; ///<! Last slot accessed
0128 
0129   std::vector<RooNormSetCache> _nsetCache ; ///<! Normalization/Integration set manager
0130   std::vector<T*> _object ;                 ///<! Payload
0131   bool _wired = false;               ///<! In wired mode, there is a single payload which is returned always
0132 
0133   ClassDefOverride(RooCacheManager,2) // Cache Manager class generic objects
0134 } ;
0135 
0136 
0137 /// Constructor for simple caches without RooAbsArg payload. A cache
0138 /// made with this constructor is not registered with its owner
0139 /// and will not receive information on server redirects and
0140 /// cache operation mode changes.
0141 template <class T>
0142 RooCacheManager<T>::RooCacheManager(Int_t maxSize) : _maxSize(maxSize)
0143 {
0144 
0145   _nsetCache.resize(_maxSize) ; // = new RooNormSetCache[maxSize] ;
0146   _object.resize(_maxSize,nullptr) ; // = new T*[maxSize] ;
0147 }
0148 
0149 
0150 /// Constructor for simple caches with RooAbsArg derived payload. A cache
0151 /// made with this constructor is registered with its owner
0152 /// and will receive information on server redirects and
0153 /// cache operation mode changes.
0154 template <class T>
0155 RooCacheManager<T>::RooCacheManager(RooAbsArg *owner, Int_t maxSize)
0156    : RooAbsCache(owner), _maxSize(maxSize)
0157 {
0158 
0159   _nsetCache.resize(_maxSize) ; // = new RooNormSetCache[maxSize] ;
0160   _object.resize(_maxSize,nullptr) ; // = new T*[maxSize] ;
0161 
0162   Int_t i ;
0163   for (i=0 ; i<_maxSize ; i++) {
0164     _object[i]=nullptr ;
0165   }
0166 
0167 }
0168 
0169 /// Copy constructor.
0170 template <class T>
0171 RooCacheManager<T>::RooCacheManager(const RooCacheManager &other, RooAbsArg *owner)
0172    : RooAbsCache(other, owner), _maxSize(other._maxSize), _size(other._size)
0173 {
0174 
0175   _nsetCache.resize(_maxSize) ; // = new RooNormSetCache[_maxSize] ;
0176   _object.resize(_maxSize,nullptr) ; // = new T*[_maxSize] ;
0177 
0178   //std::cout << "RooCacheManager:cctor(" << this << ") other = " << &other << " _size=" << _size << " _maxSize = " << _maxSize << std::endl ;
0179 
0180   Int_t i ;
0181   for (i=0 ; i<other._size ; i++) {
0182     _nsetCache[i] = other._nsetCache[i];
0183     _object[i] = nullptr ;
0184   }
0185 
0186   for (i=other._size ; i<_maxSize ; i++) {
0187     _object[i] = nullptr ;
0188   }
0189 }
0190 
0191   /// Destructor
0192 template<class T>
0193 RooCacheManager<T>::~RooCacheManager()
0194 {
0195   for (int i=0 ; i<_size ; i++) {
0196     delete _object[i] ;
0197   }
0198 }
0199 
0200 
0201   /// Clear the cache
0202 template<class T>
0203 void RooCacheManager<T>::reset()
0204 {
0205   for (int i=0 ; i<_maxSize ; i++) {
0206     delete _object[i] ;
0207     _object[i]=nullptr ;
0208     _nsetCache[i].clear() ;
0209   }
0210   _lastIndex = -1 ;
0211   _size = 0 ;
0212 }
0213 
0214 
0215 /// Clear the cache payload but retain slot mapping w.r.t to
0216 /// normalization and integration sets.
0217 template<class T>
0218 void RooCacheManager<T>::sterilize()
0219 {
0220   Int_t i ;
0221   for (i=0 ; i<_maxSize ; i++) {
0222     delete _object[i] ;
0223     _object[i]=nullptr ;
0224   }
0225 }
0226 
0227 
0228 /// Insert payload object 'obj' in cache indexed on nset,iset and isetRangeName.
0229 template<class T>
0230 Int_t RooCacheManager<T>::setObj(const RooArgSet* nset, const RooArgSet* iset, T* obj, const TNamed* isetRangeName)
0231 {
0232   // Check if object is already registered
0233   Int_t sterileIdx(-1) ;
0234   if (getObj(nset,iset,&sterileIdx,isetRangeName)) {
0235     delete obj; // important! do not forget to cleanup memory
0236     return lastIndex() ;
0237   }
0238 
0239 
0240   if (sterileIdx>=0) {
0241     // Found sterile slot that can should be recycled [ sterileIndex only set if isetRangeName matches ]
0242 
0243     if (sterileIdx>=_maxSize) {
0244       //cout << "RooCacheManager<T>::setObj()/SI increasing object cache size from " << _maxSize << " to " << sterileIdx+4 << std::endl ;
0245       _maxSize = sterileIdx+4;
0246       _object.resize(_maxSize,nullptr) ;
0247       _nsetCache.resize(_maxSize) ;
0248     }
0249 
0250 
0251     _object[sterileIdx] = obj ;
0252 
0253     // Allow optional post-processing of object inserted in cache
0254     insertObjectHook(*obj) ;
0255 
0256     return lastIndex() ;
0257   }
0258 
0259   if (_size>=_maxSize-1) {
0260     //cout << "RooCacheManager<T>::setObj() increasing object cache size from " << _maxSize << " to " << _maxSize*2 << std::endl ;
0261     _maxSize *=2 ;
0262     _object.resize(_maxSize,nullptr) ;
0263     _nsetCache.resize(_maxSize) ;
0264   }
0265 
0266   //cout << "RooCacheManager::setObj<T>(" << this << ") _size = " << _size << " _maxSize = " << _maxSize << std::endl ;
0267   _nsetCache[_size].autoCache(_owner,nset,iset,isetRangeName,true) ;
0268   if (_object[_size]) {
0269     delete _object[_size] ;
0270   }
0271 
0272   _object[_size] = obj ;
0273   _size++ ;
0274 
0275   // Allow optional post-processing of object inserted in cache
0276   insertObjectHook(*obj) ;
0277 
0278   // Unwire cache in case it was wired
0279   _wired = false ;
0280 
0281   return _size-1 ;
0282 }
0283 
0284 
0285 /// Retrieve payload object indexed on nset,uset amd isetRangeName
0286 /// If sterileIdx is not null, it is set to the index of the sterile
0287 /// slot in cacse such a slot is recycled.
0288 template<class T>
0289 T* RooCacheManager<T>::getObj(const RooArgSet* nset, const RooArgSet* iset, Int_t* sterileIdx, const TNamed* isetRangeName)
0290 {
0291   // Fast-track for wired mode
0292   if (_wired) {
0293     if(_object[0]==nullptr && sterileIdx) *sterileIdx=0 ;
0294     return _object[0] ;
0295   }
0296 
0297   Int_t i ;
0298   for (i=0 ; i<_size ; i++) {
0299     if (_nsetCache[i].contains(nset,iset,isetRangeName)==true) {
0300       _lastIndex = i ;
0301       if(_object[i]==nullptr && sterileIdx) *sterileIdx=i ;
0302       return _object[i] ;
0303     }
0304   }
0305 
0306   for (i=0 ; i<_size ; i++) {
0307     if (_nsetCache[i].autoCache(_owner,nset,iset,isetRangeName,false)==false) {
0308       _lastIndex = i ;
0309       if(_object[i]==nullptr && sterileIdx) *sterileIdx=i ;
0310       return _object[i] ;
0311     }
0312   }
0313 
0314   return nullptr ;
0315 }
0316 
0317 
0318 /// Retrieve payload object by slot index.
0319 template<class T>
0320 T* RooCacheManager<T>::getObjByIndex(Int_t index) const
0321 {
0322   if (index<0||index>=_size) {
0323     oocoutE(_owner,ObjectHandling) << "RooCacheManager::getNormListByIndex: ERROR index ("
0324                << index << ") out of range [0," << _size-1 << "]" << std::endl ;
0325     return nullptr ;
0326   }
0327   return _object[index] ;
0328 }
0329 
0330 
0331 /// Create RooArgSet containing the objects that are both in the cached set 1
0332 /// with a given index and an input argSet.
0333 template <class T>
0334 RooArgSet RooCacheManager<T>::selectFromSet1(RooArgSet const &argSet, int index) const
0335 {
0336    RooArgSet output;
0337    for (auto const &name : ROOT::Split(_nsetCache.at(index).nameSet1(), ":")) {
0338       if (RooAbsArg *arg = argSet.find(name.c_str())) {
0339          output.add(*arg);
0340       }
0341    }
0342    return output;
0343 }
0344 
0345 /// Create RooArgSet containing the objects that are both in the cached set 2
0346 /// with a given index and an input argSet.
0347 template <class T>
0348 RooArgSet RooCacheManager<T>::selectFromSet2(RooArgSet const &argSet, int index) const
0349 {
0350    RooArgSet output;
0351    for (auto const &name : ROOT::Split(_nsetCache.at(index).nameSet2(), ":")) {
0352       if (RooAbsArg *arg = argSet.find(name.c_str())) {
0353          output.add(*arg);
0354       }
0355    }
0356    return output;
0357 }
0358 
0359 #endif