Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*****************************************************************************
0002  * Project: RooFit                                                           *
0003  * Package: RooFitCore                                                       *
0004  *    File: $Id: RooSetProxy.h,v 1.21 2007/07/13 21:24:36 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 
0017 /**
0018 \class RooCollectionProxy
0019 \ingroup Roofitcore
0020 Concrete proxy for RooArgSet or RooArgList objects.
0021 A RooCollectionProxy is the general mechanism to store a RooArgSet or RooArgList
0022 with RooAbsArgs in a RooAbsArg.
0023 Creating a RooCollectionProxy adds all members of the proxied RooArgSet to the proxy owners
0024 server list (thus receiving value/shape dirty flags from it) and
0025 registers itself with the owning class. The latter allows the
0026 owning class to update the pointers of RooArgSet or RooArgList contents to reflect
0027 the serverRedirect changes.
0028 **/
0029 
0030 #ifndef roofit_roofitcore_RooFit_RooCollectionProxy_h
0031 #define roofit_roofitcore_RooFit_RooCollectionProxy_h
0032 
0033 #include <RooAbsArg.h>
0034 #include <RooAbsProxy.h>
0035 #include <RooArgSet.h>
0036 #include <RooMsgService.h>
0037 
0038 #include <ROOT/RConfig.hxx> // for R__SUGGEST_ALTERNATIVE
0039 
0040 #include <exception>
0041 
0042 template <class RooCollection_t>
0043 class RooCollectionProxy final : public RooCollection_t, public RooAbsProxy {
0044 public:
0045    // Constructors, assignment etc.
0046    RooCollectionProxy() {}
0047 
0048    /// Construct proxy with given name and description, with given owner
0049    /// The default value and shape dirty propagation of the set contents
0050    /// to the set owner is controlled by flags defValueServer and defShapeServer.
0051    RooCollectionProxy(const char *inName, const char * /*desc*/, RooAbsArg *owner, bool defValueServer = true,
0052                       bool defShapeServer = false)
0053       : RooCollection_t(inName), _owner(owner), _defValueServer(defValueServer), _defShapeServer(defShapeServer)
0054    {
0055       _owner->registerProxy(*this);
0056    }
0057 
0058    /// Copy constructor.
0059    /// \note Copying a collection proxy and giving it a name different from the
0060    /// original proxy doesn't make sense in the context of how this class is
0061    /// used. The copy constructor that doesn't take a name as the first
0062    /// parameter should be preferred.
0063    template <class Other_t>
0064    RooCollectionProxy(const char *inName, RooAbsArg *owner, const Other_t &other)
0065       R__SUGGEST_ALTERNATIVE("Copying a collection proxy and giving it a name different from the original proxy "
0066                              "doesn't make sense in the context of how this class is used. The copy constructor that "
0067                              "doesn't take a name as the first parameter should be preferred.")
0068       : RooCollection_t(other, inName),
0069         _owner(owner),
0070         _defValueServer(other.defValueServer()),
0071         _defShapeServer(other.defShapeServer())
0072    {
0073       _owner->registerProxy(*this);
0074    }
0075 
0076    /// Copy constructor.
0077    template <class Other_t>
0078    RooCollectionProxy(RooAbsArg *owner, const Other_t &other)
0079       : RooCollection_t(other, other.GetName()),
0080         _owner(owner),
0081         _defValueServer(other.defValueServer()),
0082         _defShapeServer(other.defShapeServer())
0083    {
0084       _owner->registerProxy(*this);
0085    }
0086 
0087    /// Initializes this RooCollection proxy from another proxy. Should not be
0088    /// considered part of the public interface, only to be used by IO.
0089    template <class Other_t>
0090    void initializeAfterIOConstructor(RooAbsArg *owner, const Other_t &other)
0091    {
0092 
0093       // Copy all attributes from "other"
0094       _owner = owner;
0095       _defValueServer = other.defValueServer();
0096       _defShapeServer = other.defShapeServer();
0097       RooCollection_t::setName(other.GetName());
0098 
0099       // Add the elements. This should not be done with
0100       // RooCollectionProxy::add(), but with the base class method. Otherwise,
0101       // _owner->addServer() is called when adding each element, which we don't
0102       // want for IO because the list of servers are already filled when
0103       // reading the server list of the object in the file.
0104       RooCollection_t::add(other);
0105 
0106       // Don't do _owner->registerProxy(*this) here! The proxy list will also be copied separately.
0107    }
0108 
0109    // Assignment is deleted because it is not clear how it should behave.
0110    // Should default assignment be used? But then, it will use the assignment
0111    // operators of the RooFit collections, which actually don't do assignment,
0112    // but value synchronization! Should it be re-implemented to be actual
0113    // assignment? That would be inconsistent with the base class! So it's
0114    // better to not support it at all.
0115    RooCollectionProxy &operator=(RooCollectionProxy const &other) = delete;
0116    RooCollectionProxy &operator=(RooCollectionProxy &&other) = delete;
0117 
0118    ~RooCollectionProxy() override
0119    {
0120       if (_owner)
0121          _owner->unRegisterProxy(*this);
0122    }
0123 
0124    const char *name() const override { return RooCollection_t::GetName(); }
0125 
0126    // List content management (modified for server hooks)
0127    using RooAbsCollection::add;
0128    bool add(const RooAbsArg &var, bool valueServer, bool shapeServer, bool silent);
0129 
0130    /// Overloaded RooCollection_t::add() method inserts 'var' into set
0131    /// and registers 'var' as server to owner with default value
0132    /// and shape dirty flag propagation.
0133    bool add(const RooAbsArg &var, bool silent = false) override
0134    {
0135       return add(var, _defValueServer, _defShapeServer, silent);
0136    }
0137 
0138    using RooAbsCollection::addOwned;
0139 
0140 // The following function is not memory safe, because it takes ownership of var
0141 // without moving it. It is not publicly available in the memory safe
0142 // interfaces mode.
0143 #ifdef ROOFIT_MEMORY_SAFE_INTERFACES
0144 protected:
0145 #endif
0146    bool addOwned(RooAbsArg &var, bool silent = false) override;
0147 #ifdef ROOFIT_MEMORY_SAFE_INTERFACES
0148 public:
0149 #endif
0150 
0151    using RooAbsCollection::addClone;
0152    RooAbsArg *addClone(const RooAbsArg &var, bool silent = false) override;
0153 
0154    bool replace(const RooAbsArg &var1, const RooAbsArg &var2) override;
0155    bool remove(const RooAbsArg &var, bool silent = false, bool matchByNameOnly = false) override;
0156 
0157    /// Remove each argument in the input list from our list using remove(const RooAbsArg&).
0158    /// and remove each argument as server to owner
0159    bool remove(const RooAbsCollection &list, bool silent = false, bool matchByNameOnly = false)
0160    {
0161       bool result(false);
0162       for (auto const &arg : list) {
0163          result |= remove(*arg, silent, matchByNameOnly);
0164       }
0165       return result;
0166    }
0167 
0168    void removeAll() override;
0169 
0170    void print(std::ostream &os, bool addContents = false) const override;
0171 
0172    /// Assign values of arguments on other set to arguments in this set.
0173    RooCollectionProxy &operator=(const RooCollection_t &other)
0174    {
0175       RooCollection_t::operator=(other);
0176       return *this;
0177    }
0178 
0179    bool defValueServer() const { return _defValueServer; }
0180    bool defShapeServer() const { return _defShapeServer; }
0181 
0182 private:
0183    RooAbsArg *_owner = nullptr;
0184    bool _defValueServer = false;
0185    bool _defShapeServer = false;
0186 
0187    bool
0188    changePointer(const RooAbsCollection &newServerSet, bool nameChange = false, bool factoryInitMode = false) override;
0189 
0190    bool changePointer(std::unordered_map<RooAbsArg *, RooAbsArg *> const &replacements) override;
0191 
0192    void checkValid() const
0193    {
0194       if (!_owner) {
0195          throw std::runtime_error(
0196             "Attempt to add elements to a RooSetProxy or RooListProxy without owner!"
0197             " Please avoid using the RooListProxy default constructor, which should only be used by IO.");
0198       }
0199    }
0200 
0201    ClassDefOverride(RooCollectionProxy, 1)
0202 };
0203 
0204 ////////////////////////////////////////////////////////////////////////////////
0205 /// Overloaded RooCollection_t::add() method insert object into set
0206 /// and registers object as server to owner with given value
0207 /// and shape dirty flag propagation requests
0208 
0209 template <class RooCollection_t>
0210 bool RooCollectionProxy<RooCollection_t>::add(const RooAbsArg &var, bool valueServer, bool shapeServer, bool silent)
0211 {
0212    checkValid();
0213    bool ret = RooCollection_t::add(var, silent);
0214    if (ret) {
0215       _owner->addServer((RooAbsArg &)var, valueServer, shapeServer);
0216    }
0217    return ret;
0218 }
0219 
0220 ////////////////////////////////////////////////////////////////////////////////
0221 /// Overloaded RooCollection_t::addOwned() method insert object into owning set
0222 /// and registers object as server to owner with default value
0223 /// and shape dirty flag propagation
0224 
0225 template <class RooCollection_t>
0226 bool RooCollectionProxy<RooCollection_t>::addOwned(RooAbsArg &var, bool silent)
0227 {
0228    checkValid();
0229    bool ret = RooCollection_t::addOwned(var, silent);
0230    if (ret) {
0231       _owner->addServer((RooAbsArg &)var, _defValueServer, _defShapeServer);
0232    }
0233    return ret;
0234 }
0235 
0236 ////////////////////////////////////////////////////////////////////////////////
0237 /// Overloaded RooCollection_t::addClone() method insert clone of object into owning set
0238 /// and registers cloned object as server to owner with default value
0239 /// and shape dirty flag propagation
0240 
0241 template <class RooCollection_t>
0242 RooAbsArg *RooCollectionProxy<RooCollection_t>::addClone(const RooAbsArg &var, bool silent)
0243 {
0244    checkValid();
0245    RooAbsArg *ret = RooCollection_t::addClone(var, silent);
0246    if (ret) {
0247       _owner->addServer((RooAbsArg &)var, _defValueServer, _defShapeServer);
0248    }
0249    return ret;
0250 }
0251 
0252 ////////////////////////////////////////////////////////////////////////////////
0253 /// Replace object 'var1' in set with 'var2'. Deregister var1 as
0254 /// server from owner and register var2 as server to owner with
0255 /// default value and shape dirty propagation flags
0256 
0257 template <class RooCollection_t>
0258 bool RooCollectionProxy<RooCollection_t>::replace(const RooAbsArg &var1, const RooAbsArg &var2)
0259 {
0260    bool ret = RooCollection_t::replace(var1, var2);
0261    if (ret) {
0262       if (!RooCollection_t::isOwning())
0263          _owner->removeServer((RooAbsArg &)var1);
0264       _owner->addServer((RooAbsArg &)var2, _owner->isValueServer(var1), _owner->isShapeServer(var2));
0265    }
0266    return ret;
0267 }
0268 
0269 ////////////////////////////////////////////////////////////////////////////////
0270 /// Remove object 'var' from set and deregister 'var' as server to owner.
0271 
0272 template <class RooCollection_t>
0273 bool RooCollectionProxy<RooCollection_t>::remove(const RooAbsArg &var, bool silent, bool matchByNameOnly)
0274 {
0275    bool ret = RooCollection_t::remove(var, silent, matchByNameOnly);
0276    if (ret && !RooCollection_t::isOwning()) {
0277       _owner->removeServer((RooAbsArg &)var);
0278    }
0279    return ret;
0280 }
0281 
0282 ////////////////////////////////////////////////////////////////////////////////
0283 /// Remove all argument inset using remove(const RooAbsArg&).
0284 /// and remove each argument as server to owner
0285 
0286 template <class RooCollection_t>
0287 void RooCollectionProxy<RooCollection_t>::removeAll()
0288 {
0289    if (!RooCollection_t::isOwning()) {
0290       for (auto const &arg : *this) {
0291          if (!RooCollection_t::isOwning()) {
0292             _owner->removeServer(*arg);
0293          }
0294       }
0295    }
0296 
0297    RooCollection_t::removeAll();
0298 }
0299 
0300 ////////////////////////////////////////////////////////////////////////////////
0301 /// Process server change operation on owner. Replace elements in set with equally
0302 /// named objects in 'newServerList'
0303 
0304 template <class RooCollection_t>
0305 bool RooCollectionProxy<RooCollection_t>::changePointer(const RooAbsCollection &newServerList, bool nameChange,
0306                                                         bool factoryInitMode)
0307 {
0308    if (RooCollection_t::empty()) {
0309       if (factoryInitMode) {
0310          for (const auto arg : newServerList) {
0311             if (arg != _owner) {
0312                add(*arg, true);
0313             }
0314          }
0315       } else {
0316          return true;
0317       }
0318    }
0319 
0320    bool error(false);
0321    for (auto const &arg : *this) {
0322       RooAbsArg *newArg = arg->findNewServer(newServerList, nameChange);
0323       if (newArg && newArg != _owner)
0324          error |= !RooCollection_t::replace(*arg, *newArg);
0325    }
0326    return !error;
0327 }
0328 
0329 template <class RooCollection_t>
0330 bool RooCollectionProxy<RooCollection_t>::changePointer(
0331    std::unordered_map<RooAbsArg *, RooAbsArg *> const &replacements)
0332 {
0333    bool error(false);
0334    for (auto const &arg : *this) {
0335       auto newArgFound = replacements.find(arg);
0336       if (newArgFound != replacements.end()) {
0337          error |= !RooCollection_t::replace(*arg, *newArgFound->second);
0338       }
0339    }
0340    return !error;
0341 }
0342 
0343 ////////////////////////////////////////////////////////////////////////////////
0344 /// Printing name of proxy on ostream. If addContents is true
0345 /// also print names of objects in set
0346 
0347 template <class RooCollection_t>
0348 void RooCollectionProxy<RooCollection_t>::print(std::ostream &os, bool addContents) const
0349 {
0350    if (!addContents) {
0351       os << name() << "=";
0352       RooCollection_t::printStream(os, RooPrintable::kValue, RooPrintable::kInline);
0353    } else {
0354       os << name() << "=(";
0355       bool first2(true);
0356       for (auto const &arg : *this) {
0357          if (first2) {
0358             first2 = false;
0359          } else {
0360             os << ",";
0361          }
0362          arg->printStream(os, RooPrintable::kValue | RooPrintable::kName, RooPrintable::kInline);
0363       }
0364       os << ")";
0365    }
0366 }
0367 
0368 using RooSetProxy = RooCollectionProxy<RooArgSet>;
0369 
0370 #endif