Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:11:17

0001 /*****************************************************************************
0002  * Project: RooFit                                                           *
0003  * Package: RooFitCore                                                       *
0004  *    File: $Id: RooAbsCollection.h,v 1.26 2007/08/09 19:55:47 wouter 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_ABS_COLLECTION
0017 #define ROO_ABS_COLLECTION
0018 
0019 #include <RooAbsArg.h>
0020 #include <RooCmdArg.h>
0021 #include <RooFit/UniqueId.h>
0022 #include <RooLinkedListIter.h>
0023 #include <RooPrintable.h>
0024 
0025 // The range casts are not used in this file, but if you want to work with
0026 // RooFit collections you also want to have static_range_cast and
0027 // dynamic_range_cast available without including RangeCast.h every time.
0028 #include <ROOT/RRangeCast.hxx>
0029 
0030 #include <ROOT/RSpan.hxx>
0031 
0032 #include <TClass.h>
0033 #include <TObject.h>
0034 #include <TString.h>
0035 
0036 #include <string>
0037 #include <unordered_map>
0038 #include <vector>
0039 #include <type_traits>
0040 #include <memory>
0041 
0042 
0043 // To make ROOT::RangeStaticCast available under the name static_range_cast.
0044 template <typename T, typename Range_t>
0045 ROOT::RRangeCast<T, false, Range_t> static_range_cast(Range_t &&coll)
0046 {
0047    return ROOT::RangeStaticCast<T>(std::forward<Range_t>(coll));
0048 }
0049 
0050 
0051 // To make ROOT::RangeDynCast available under the dynamic_range_cast.
0052 template <typename T, typename Range_t>
0053 ROOT::RRangeCast<T, true, Range_t> dynamic_range_cast(Range_t &&coll)
0054 {
0055    return ROOT::RangeDynCast<T>(std::forward<Range_t>(coll));
0056 }
0057 
0058 
0059 namespace RooFit {
0060 namespace Detail {
0061 struct HashAssistedFind;
0062 }
0063 }
0064 
0065 class RooAbsCollection : public TObject, public RooPrintable {
0066 public:
0067   using Storage_t = std::vector<RooAbsArg*>;
0068   using const_iterator = Storage_t::const_iterator;
0069 
0070 
0071   // Constructors, assignment etc.
0072   RooAbsCollection();
0073   RooAbsCollection(const char *name);
0074   virtual TObject* clone(const char* newname) const = 0 ;
0075   virtual TObject* create(const char* newname) const = 0 ;
0076   TObject* Clone(const char* newname=nullptr) const override {
0077     return clone(newname?newname:GetName()) ;
0078   }
0079   ~RooAbsCollection() override;
0080 
0081   // Create a copy of an existing list. New variables cannot be added
0082   // to a copied list. The variables in the copied list are independent
0083   // of the original variables.
0084   RooAbsCollection(const RooAbsCollection& other, const char *name="");
0085   RooAbsCollection& operator=(const RooAbsCollection& other);
0086 
0087   void assign(const RooAbsCollection& other) const;
0088   RooAbsCollection &assignValueOnly(const RooAbsCollection& other, bool forceIfSizeOne=false);
0089   void assignFast(const RooAbsCollection& other, bool setValDirty=true) const;
0090 
0091   // Move constructor
0092   RooAbsCollection(RooAbsCollection && other);
0093 
0094   /// Returns a unique ID that is different for every instantiated
0095   /// RooAbsCollection. This ID can be used to check whether two collections
0096   /// are the same object, which is safer than memory address comparisons that
0097   /// might result in false positives when memory is recycled.
0098   RooFit::UniqueId<RooAbsCollection> const& uniqueId() const { return _uniqueId; }
0099 
0100   // Copy list and contents (and optionally 'deep' servers)
0101   RooAbsCollection *snapshot(bool deepCopy=true) const ;
0102   bool snapshot(RooAbsCollection& output, bool deepCopy=true) const ;
0103 
0104   /// Set the size at which the collection will automatically start using an extra
0105   /// lookup table instead of performing a linear search.
0106   void setHashTableSize(Int_t number) {
0107     _sizeThresholdForMapSearch = number;
0108   }
0109   /// Query the size at which the collection will automatically start using an extra
0110   /// lookup table instead of performing a linear search.
0111   Int_t getHashTableSize() const {
0112     return _sizeThresholdForMapSearch;
0113   }
0114 
0115   /// Const access to the underlying stl container.
0116   Storage_t const& get() const { return _list; }
0117 
0118   // List content management
0119   virtual bool add(const RooAbsArg& var, bool silent=false) ;
0120 // The following function is not memory safe, because it takes ownership of var
0121 // without moving it. It is not publicly available in the memory safe
0122 // interfaces mode.
0123 #ifdef ROOFIT_MEMORY_SAFE_INTERFACES
0124 protected:
0125 #endif
0126   virtual bool addOwned(RooAbsArg& var, bool silent=false);
0127 #ifdef ROOFIT_MEMORY_SAFE_INTERFACES
0128 public:
0129 #endif
0130   bool addOwned(std::unique_ptr<RooAbsArg> var, bool silent=false);
0131   virtual RooAbsArg *addClone(const RooAbsArg& var, bool silent=false) ;
0132   virtual bool replace(const RooAbsArg& var1, const RooAbsArg& var2) ;
0133   bool replace(RooAbsArg* var1, std::unique_ptr<RooAbsArg> var2) ;
0134   virtual bool remove(const RooAbsArg& var, bool silent=false, bool matchByNameOnly=false) ;
0135   virtual void removeAll() ;
0136 
0137   template<typename Iterator_t,
0138       typename value_type = typename std::remove_pointer<typename std::iterator_traits<Iterator_t>::value_type>,
0139       typename = std::enable_if<std::is_convertible<const value_type*, const RooAbsArg*>::value> >
0140   bool add(Iterator_t beginIt, Iterator_t endIt, bool silent=false) {
0141     bool result = false ;
0142     _list.reserve(_list.size() + std::distance(beginIt, endIt));
0143     for (auto it = beginIt; it != endIt; ++it) {
0144       result |= add(**it,silent);
0145     }
0146     return result;
0147   }
0148   ////////////////////////////////////////////////////////////////////////////////
0149   /// Add a collection of arguments to this collection by calling add()
0150   /// for each element in the source collection
0151   bool add(const RooAbsCollection& list, bool silent=false) {
0152     return add(list._list.begin(), list._list.end(), silent);
0153   }
0154    /**
0155     * \brief Adds elements of a given RooAbsCollection to the container if they match the specified type.
0156     *
0157     * This function iterates through the elements of the provided RooAbsCollection and checks if each element
0158     * matches the specified type. If any element doesn't match the type, it throws an exception.
0159     *
0160     * \tparam Arg_t The type to match for elements in the collection. Must inherit from RooAbsArg.
0161     * \param list The RooAbsCollection containing elements to be added.
0162     * \param silent Forwarded to the non-typed add function. If true,
0163     *               suppresses error messages when adding elements, e.g. when
0164     *               the collection is a RooArgSet and the element is already in
0165     *               the set.
0166     * \return Returns true if all elements could be added, else false.
0167     *
0168     * \throws std::invalid_argument if an element in the collection doesn't match the specified type.
0169     */
0170    template <class Arg_t>
0171    bool addTyped(const RooAbsCollection &list, bool silent = false)
0172    {
0173       for (RooAbsArg *arg : list) {
0174          if (!dynamic_cast<Arg_t *>(arg)) {
0175             throwAddTypedException(Arg_t::Class(), arg);
0176          }
0177       }
0178       return add(list, silent);
0179    }
0180   virtual bool addOwned(const RooAbsCollection& list, bool silent=false);
0181   bool addOwned(RooAbsCollection&& list, bool silent=false);
0182   virtual void   addClone(const RooAbsCollection& list, bool silent=false);
0183   bool replace(const RooAbsCollection &other);
0184   bool remove(const RooAbsCollection& list, bool silent=false, bool matchByNameOnly=false) ;
0185   template<class forwardIt>
0186   void remove(forwardIt rangeBegin, forwardIt rangeEnd, bool silent = false, bool matchByNameOnly = false) {
0187       for (forwardIt it = rangeBegin; it != rangeEnd; ++it) {
0188         static_assert(std::is_same<
0189             typename std::iterator_traits<forwardIt>::value_type,
0190             RooAbsArg*>::value, "Can only remove lists of RooAbsArg*.");
0191         auto castedElm = static_cast<RooAbsArg*>(*it);
0192         remove(*castedElm, silent, matchByNameOnly);
0193       }
0194   }
0195 
0196    // Utilities functions when used as configuration object
0197    double getRealValue(const char* name, double defVal=0.0, bool verbose=false) const ;
0198    const char* getCatLabel(const char* name, const char* defVal="", bool verbose=false) const ;
0199    Int_t getCatIndex(const char* name, Int_t defVal=0, bool verbose=false) const ;
0200    const char* getStringValue(const char* name, const char* defVal="", bool verbose=false) const ;
0201    bool setRealValue(const char* name, double newVal=0.0, bool verbose=false) ;
0202    bool setCatLabel(const char* name, const char* newVal="", bool verbose=false) ;
0203    bool setCatIndex(const char* name, Int_t newVal=0, bool verbose=false) ;
0204    bool setStringValue(const char* name, const char* newVal="", bool verbose=false) ;
0205 
0206   // Group operations on AbsArgs
0207   void setAttribAll(const Text_t* name, bool value=true) ;
0208 
0209   // List search methods
0210   RooAbsArg *find(const char *name) const ;
0211   RooAbsArg *find(const RooAbsArg&) const ;
0212 
0213   /// Find object by name in the collection
0214   TObject* FindObject(const char* name) const override { return find(name); }
0215 
0216   /// Find object in the collection, Note: matching by object name, like the find() method
0217   TObject* FindObject(const TObject* obj) const override { auto arg = dynamic_cast<const RooAbsArg*>(obj); return (arg) ? find(*arg) : nullptr; }
0218 
0219   /// Check if collection contains an argument with the same name as var.
0220   /// To check for a specific instance, use containsInstance().
0221   bool contains(const RooAbsArg& var) const {
0222     return find(var) != nullptr;
0223   }
0224   /// Check if this exact instance is in this collection.
0225   virtual bool containsInstance(const RooAbsArg& var) const {
0226     return std::find(_list.begin(), _list.end(), &var) != _list.end();
0227   }
0228   RooAbsCollection* selectByAttrib(const char* name, bool value) const ;
0229   bool selectCommon(const RooAbsCollection& refColl, RooAbsCollection& outColl) const ;
0230   RooAbsCollection* selectCommon(const RooAbsCollection& refColl) const ;
0231   RooAbsCollection* selectByName(const char* nameList, bool verbose=false) const ;
0232   bool equals(const RooAbsCollection& otherColl) const ;
0233   bool hasSameLayout(const RooAbsCollection& other) const;
0234 
0235   template<typename Iterator_t,
0236       typename value_type = typename std::remove_pointer<typename std::iterator_traits<Iterator_t>::value_type>,
0237       typename = std::enable_if<std::is_convertible<const value_type*, const RooAbsArg*>::value> >
0238   bool overlaps(Iterator_t otherCollBegin, Iterator_t otherCollEnd) const  {
0239     for (auto it = otherCollBegin; it != otherCollEnd; ++it) {
0240       if (find(**it)) {
0241         return true ;
0242       }
0243     }
0244     return false ;
0245   }
0246 
0247   ////////////////////////////////////////////////////////////////////////////////
0248   /// Check if this and other collection have common entries
0249   bool overlaps(const RooAbsCollection& otherColl) const {
0250     return overlaps(otherColl._list.begin(), otherColl._list.end());
0251   }
0252 
0253   /// TIterator-style iteration over contained elements.
0254   /// \note These iterators are slow. Use begin() and end() or
0255   /// range-based for loop instead.
0256   inline TIterator* createIterator(bool dir = kIterForward) const
0257   R__DEPRECATED(6,34, "begin(), end() and range-based for loops.") {
0258     // Create and return an iterator over the elements in this collection
0259     return new RooLinkedListIter(makeLegacyIterator(dir));
0260   }
0261 
0262   /// TIterator-style iteration over contained elements.
0263   /// \note This iterator is slow. Use begin() and end() or range-based for loop instead.
0264   RooLinkedListIter iterator(bool dir = kIterForward) const
0265   R__DEPRECATED(6,34, "begin(), end() and range-based for loops.") {
0266     return RooLinkedListIter(makeLegacyIterator(dir));
0267   }
0268 
0269   /// One-time forward iterator.
0270   /// \note Use begin() and end() or range-based for loop instead.
0271   RooFIter fwdIterator() const
0272   R__DEPRECATED(6,34, "begin(), end() and range-based for loops.") {
0273     return RooFIter(makeLegacyIterator());
0274   }
0275 
0276   const_iterator begin() const {
0277     return _list.begin();
0278   }
0279 
0280   const_iterator end() const {
0281     return _list.end();
0282   }
0283 
0284   Storage_t::const_reverse_iterator rbegin() const {
0285     return _list.rbegin();
0286   }
0287 
0288   Storage_t::const_reverse_iterator rend() const {
0289       return _list.rend();
0290     }
0291 
0292   Storage_t::size_type size() const {
0293     return _list.size();
0294   }
0295 
0296   bool empty() const {
0297     return _list.empty();
0298   }
0299 
0300   void reserve(Storage_t::size_type count) {
0301     _list.reserve(count);
0302   }
0303 
0304   /// Clear contents. If the collection is owning, it will also delete the contents.
0305   void clear() {
0306     removeAll();
0307   }
0308 
0309   /// Return the number of elements in the collection
0310   inline Int_t getSize() const R__SUGGEST_ALTERNATIVE("size() returns true size.") {
0311     return _list.size();
0312   }
0313 
0314   inline RooAbsArg *first() const {
0315     // Return the first element in this collection
0316     // calling front on an empty container is undefined
0317     return _list.empty() ? nullptr : _list.front();
0318   }
0319 
0320   RooAbsArg * operator[](Storage_t::size_type i) const {
0321     return _list[i];
0322   }
0323 
0324 
0325   /// Returns index of given arg, or -1 if arg is not in the collection.
0326   inline Int_t index(const RooAbsArg* arg) const {
0327     auto item = std::find(_list.begin(), _list.end(), arg);
0328     return item != _list.end() ? item - _list.begin() : -1;
0329   }
0330 
0331   /// Returns index of given arg, or -1 if arg is not in the collection.
0332   inline Int_t index(const RooAbsArg& arg) const {
0333     return index(&arg);
0334   }
0335 
0336   Int_t index(const char* name) const;
0337 
0338   inline void Print(Option_t *options= nullptr) const override {
0339     // Printing interface (human readable)
0340     printStream(defaultPrintStream(),defaultPrintContents(options),defaultPrintStyle(options));
0341   }
0342   std::string contentsString() const ;
0343 
0344 
0345   void printName(std::ostream& os) const override ;
0346   void printTitle(std::ostream& os) const override ;
0347   void printClassName(std::ostream& os) const override ;
0348   void printValue(std::ostream& os) const override ;
0349   void printMultiline(std::ostream& os, Int_t contents, bool verbose=false, TString indent="") const override ;
0350 
0351   Int_t defaultPrintContents(Option_t* opt) const override ;
0352 
0353   // Latex printing methods
0354   void printLatex(const RooCmdArg& arg1={}, const RooCmdArg& arg2={},
0355         const RooCmdArg& arg3={}, const RooCmdArg& arg4={},
0356         const RooCmdArg& arg5={}, const RooCmdArg& arg6={},
0357         const RooCmdArg& arg7={}, const RooCmdArg& arg8={}) const ;
0358   void printLatex(std::ostream& ofs, Int_t ncol, const char* option="NEYU", Int_t sigDigit=1,
0359                   const RooLinkedList& siblingLists=RooLinkedList(), const RooCmdArg* formatCmd=nullptr) const ;
0360 
0361   void setName(const char *name) {
0362     // Set name of collection
0363     _name= name;
0364   }
0365   const char* GetName() const override {
0366     // Return namer of collection
0367     return _name.Data() ;
0368   }
0369   bool isOwning() const {
0370     // Does collection own contents?
0371     return _ownCont ;
0372   }
0373 
0374   bool allInRange(const char* rangeSpec) const ;
0375 
0376   void dump() const ;
0377 
0378   void releaseOwnership() { _ownCont = false ; }
0379   void takeOwnership() { _ownCont = true ; }
0380 
0381   void sort(bool reverse = false);
0382   void sortTopologically();
0383 
0384   void RecursiveRemove(TObject *obj) override;
0385 
0386   void useHashMapForFind(bool flag) const;
0387 
0388   // For use in the RooArgList/Set(std::vector<RooAbsArgPtrOrDouble> const&) constructor.
0389   // Can be replaced with std::variant when C++17 is the minimum supported standard.
0390   struct RooAbsArgPtrOrDouble {
0391     RooAbsArgPtrOrDouble(RooAbsArg & arg) : ptr{&arg}, hasPtr{true} {}
0392     RooAbsArgPtrOrDouble(double x) : val{x}, hasPtr{false} {}
0393 
0394     RooAbsArg * ptr = nullptr;
0395     double val = 0.0;
0396     bool hasPtr = false;
0397   };
0398 
0399 protected:
0400   Storage_t _list;  ///< Actual object storage
0401   using LegacyIterator_t = TIteratorToSTLInterface<Storage_t>;
0402 
0403   bool _ownCont = false; ///< Flag to identify a list that owns its contents.
0404   TString _name;           ///< Our name.
0405   bool _allRRV = true;   ///< All contents are RRV
0406 
0407   void deleteList() ;
0408 
0409   inline TNamed* structureTag() { if (_structureTag==nullptr) makeStructureTag() ; return _structureTag ; }
0410   inline TNamed* typedStructureTag() { if (_typedStructureTag==nullptr) makeTypedStructureTag() ; return _typedStructureTag ; }
0411 
0412   mutable TNamed* _structureTag{nullptr};      ///<! Structure tag
0413   mutable TNamed* _typedStructureTag{nullptr}; ///<! Typed structure tag
0414 
0415   inline void clearStructureTags() { _structureTag = nullptr ; _typedStructureTag = nullptr ; }
0416 
0417   void makeStructureTag() {}
0418   void makeTypedStructureTag() {}
0419 
0420   /// Determine whether it's possible to add a given RooAbsArg to the collection or not.
0421   virtual bool canBeAdded(const RooAbsArg& arg, bool silent) const = 0;
0422 
0423   template<class T>
0424   static void assert_is_no_temporary(T &&) {
0425     static_assert(!std::is_rvalue_reference<T&&>::value,
0426       "A reference to a temporary RooAbsArg will be passed to a RooAbsCollection constructor! "
0427       "This is not allowed, because the collection will not own the arguments. "
0428       "Hence, the collection will contain dangling pointers when the temporary goes out of scope."
0429     );
0430   }
0431 
0432 private:
0433 
0434 #if ROOT_VERSION_CODE < ROOT_VERSION(6, 34, 00)
0435   // TODO: Remove this friend declaration and function in 6.34, where it's not
0436   // needed anymore because the deprecated legacy iterators will be removed.
0437   friend class RooWorkspace;
0438   std::unique_ptr<LegacyIterator_t> makeLegacyIterator (bool forward = true) const;
0439 #else
0440 #error "Please remove this unneeded code."
0441 #endif
0442 
0443   bool replaceImpl(const RooAbsArg& var1, const RooAbsArg& var2);
0444 
0445   using HashAssistedFind = RooFit::Detail::HashAssistedFind;
0446   mutable std::unique_ptr<HashAssistedFind> _hashAssistedFind; ///<!
0447   std::size_t _sizeThresholdForMapSearch = 100; ///<!
0448 
0449   void insert(RooAbsArg*);
0450 
0451   static void throwAddTypedException(TClass *klass, RooAbsArg *arg);
0452 
0453   const RooFit::UniqueId<RooAbsCollection> _uniqueId; //!
0454 
0455   ClassDefOverride(RooAbsCollection,3) // Collection of RooAbsArg objects
0456 };
0457 
0458 #endif