diff --git a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/DecorKeyHelpers.h b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/DecorKeyHelpers.h index 75ddb7fefd8577a8185d9f2fe044ce613f8f3eff..349c710ae2e7881fff9bf32277eeea6c5d85d2bd 100644 --- a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/DecorKeyHelpers.h +++ b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/DecorKeyHelpers.h @@ -18,7 +18,7 @@ inline std::string contKeyFromKey (const std::string& key) { const auto split = key.rfind ('.'); if (split == std::string::npos) - throw std::runtime_error ("decor key does not contain a .: " + key); + return key; return key.substr (0, split); } @@ -26,9 +26,10 @@ inline std::string decorKeyFromKey (const std::string& key) { const auto split = key.rfind ('.'); if (split == std::string::npos) - throw std::runtime_error ("decor key does not contain a .: " + key); + return ""; return key.substr (split + 1); } + } #endif diff --git a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandle.h b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandle.h index 6184d1dc8c6d83d1ff284943c7aa3fa116a2c00c..ef69de9eac3fd6a4da9ebddd117ff2e2104c6a75 100644 --- a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandle.h +++ b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandle.h @@ -22,7 +22,7 @@ #include "AsgDataHandles/ReadDecorHandleKey.h" #include "AsgDataHandles/ReadHandle.h" #include "AsgDataHandles/DecorKeyHelpers.h" -// #include "AthContainers/AuxElement.h" +#include "AthContainers/AuxElement.h" // #include "GaudiKernel/EventContext.h" // #include <type_traits> @@ -72,21 +72,21 @@ public: explicit ReadDecorHandle (const ReadDecorHandleKey<T>& key); -// /** -// * @brief Constructor from a ReadDecorHandleKey and an explicit event context. -// * @param key The key object holding the clid/key. -// * @param ctx The event context. -// * -// * This will raise an exception if the StoreGate key is blank, -// * or if the event store cannot be found. -// * -// * If the default event store has been requested, then the thread-specific -// * store from the event context will be used. -// */ -// explicit ReadDecorHandle (const ReadDecorHandleKey<T>& key, -// const EventContext& ctx); + /** + * @brief Constructor from a ReadDecorHandleKey and an explicit event context. + * @param key The key object holding the clid/key. + * @param ctx The event context. + * + * This will raise an exception if the StoreGate key is blank, + * or if the event store cannot be found. + * + * If the default event store has been requested, then the thread-specific + * store from the event context will be used. + */ + explicit ReadDecorHandle (const ReadDecorHandleKey<T>& key, + const EventContext& ctx); + - // /** // * @brief Copy constructor. // */ @@ -147,11 +147,11 @@ public: // getDataArray(); -// /** -// * @brief Test to see if this variable exists in the store, -// * for the referenced object. -// */ -// bool isAvailable(); + /** + * @brief Test to see if this variable exists in the store, + * for the referenced object. + */ + bool isAvailable(); // /** @@ -159,6 +159,12 @@ public: // */ // SG::auxid_t auxid() const; + + /** + * @brief Return the name of the decoration alias (CONT.DECOR). + */ + std::string decorKey() const; + private: /** @@ -187,6 +193,10 @@ private: const SG::AuxVectorData* vectorData(); + /// Name of the decoration alias. + std::string m_decorKey; + + /// Accessor for the aux data item. accessor_t m_acc; }; diff --git a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandle.icc b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandle.icc index eda87fd6121d2851c16520f487fee145f5c107c3..429fdb4636deab1dcdcee31c4fc40513c3cbda27 100644 --- a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandle.icc +++ b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandle.icc @@ -21,30 +21,32 @@ namespace SG { */ template <class T, class D> ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandleKey<T>& key) - : Base (key), + : Base (key.contHandleKey()), + m_decorKey (key.key()), m_acc (SG::decorKeyFromKey (key.key())) { } -// /** -// * @brief Constructor from a ReadDecorHandleKey and an explicit event context. -// * @param key The key object holding the clid/key. -// * @param ctx The event context. -// * -// * This will raise an exception if the StoreGate key is blank, -// * or if the event store cannot be found. -// * -// * If the default event store has been requested, then the thread-specific -// * store from the event context will be used. -// */ -// template <class T, class D> -// ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandleKey<T>& key, -// const EventContext& ctx) -// : Base (key, ctx), -// m_acc (SG::decorKeyFromKey (key.key())) -// { -// } +/** + * @brief Constructor from a ReadDecorHandleKey and an explicit event context. + * @param key The key object holding the clid/key. + * @param ctx The event context. + * + * This will raise an exception if the StoreGate key is blank, + * or if the event store cannot be found. + * + * If the default event store has been requested, then the thread-specific + * store from the event context will be used. + */ +template <class T, class D> +ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandleKey<T>& key, + const EventContext& ctx) + : Base (key.contHandleKey(), ctx), + m_decorKey (key.key()), + m_acc (SG::decorKeyFromKey (key.key())) +{ +} // /** @@ -53,6 +55,7 @@ ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandleKey<T>& key) // template <class T, class D> // ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandle& rhs) // : Base (rhs), +// m_decorKey (rhs.m_decorKey), // m_acc (rhs.m_acc) // { // } @@ -64,6 +67,7 @@ ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandleKey<T>& key) // template <class T, class D> // ReadDecorHandle<T, D>::ReadDecorHandle (ReadDecorHandle&& rhs) // : Base (std::move (rhs)), +// m_decorKey (std::move (rhs.m_decorKey)), // m_acc (std::move (rhs.m_acc)) // { // } @@ -77,6 +81,7 @@ ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandleKey<T>& key) // { // if (this != &rhs) { // *static_cast<Base*>(this) = rhs; +// m_decorKey = rhs.m_decorKey; // m_acc = rhs.m_acc; // } // return *this; @@ -91,6 +96,7 @@ ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandleKey<T>& key) // { // if (this != &rhs) { // *static_cast<Base*>(this) = std::move (rhs); +// m_decorKey = std::move (rhs.m_decorKey); // m_acc = std::move (rhs.m_acc); // } // return *this; @@ -106,9 +112,10 @@ ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandleKey<T>& key) * Const method; the handle does not change as a result of this. */ template <class T, class D> +inline bool ReadDecorHandle<T, D>::isPresent() const { - return this->isPresent_impl (contKeyFromKey (this->key())); + return Base::isPresent(); } @@ -154,17 +161,17 @@ ReadDecorHandle<T, D>::operator() (size_t i) // } -// /** -// * @brief Test to see if this variable exists in the store, -// * for the referenced object. -// */ -// template <class T, class D> -// inline -// bool ReadDecorHandle<T, D>::isAvailable() -// { -// const SG::AuxVectorData* vec = this->vectorData(); -// return vec && vec->isAvailable (m_acc.auxid()); -// } +/** + * @brief Test to see if this variable exists in the store, + * for the referenced object. + */ +template <class T, class D> +inline +bool ReadDecorHandle<T, D>::isAvailable() +{ + const SG::AuxVectorData* vec = this->vectorData(); + return vec && vec->isAvailable (m_acc.auxid()); +} // /** @@ -178,6 +185,17 @@ ReadDecorHandle<T, D>::operator() (size_t i) // } +/** + * @brief Return the name of the decoration alias (CONT.DECOR). + */ +template <class T, class D> +inline +std::string ReadDecorHandle<T, D>::decorKey() const +{ + return m_decorKey; +} + + /** * @brief Return the referenced object as a @c SG::AuxVectorData. * Specialization for the case of a standalone object diff --git a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandleKey.h b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandleKey.h index 83402156e06c845113995d7477bdad8e0d90d8de..ecdd8b19b45ae1925a984f5876e5864c1502526c 100644 --- a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandleKey.h +++ b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandleKey.h @@ -49,17 +49,17 @@ public: // typedef typename SG::TopBase<T>::type topbase_t; -// /** -// * @brief Constructor. -// * @param key The StoreGate key for the object. -// * @param storeName Name to use for the store, if it's not encoded in sgkey. -// * -// * The provided key may actually start with the name of the store, -// * separated by a "+": "MyStore+Obj". If no "+" is present -// * the store named by @c storeName is used. -// */ -// ReadDecorHandleKey (const std::string& key = "", -// const std::string& storeName = StoreID::storeName(StoreID::EVENT_STORE)); + /** + * @brief Constructor. + * @param key The StoreGate key for the object. + * @param storeName Name to use for the store, if it's not encoded in sgkey. + * + * The provided key may actually start with the name of the store, + * separated by a "+": "MyStore+Obj". If no "+" is present + * the store named by @c storeName is used. + */ + ReadDecorHandleKey (const std::string& key = ""); + // const std::string& storeName = StoreID::storeName(StoreID::EVENT_STORE)); /** @@ -81,9 +81,30 @@ public: const K& key = {}, const std::string& doc = ""); - - /// Can get this from the base class. - using Base::operator=; + + /** + * @brief Change the key of the object to which we're referring. + * @param sgkey The StoreGate key for the object. + * + * The provided key may actually start with the name of the store, + * separated by a "+": "MyStore+Obj". If no "+" is present, + * the store is not changed. + */ + ReadDecorHandleKey& operator= (const std::string& sgkey); + + + /** + * @brief Change the key of the object to which we're referring. + * @param sgkey The StoreGate key for the object. + * + * The provided key may actually start with the name of the store, + * separated by a "+": "MyStore+Obj". If no "+" is present + * the store is not changed. A key name that starts with a slash + * is interpreted as a hierarchical key name, not an empty store name. + * + * Returns failure the key string format is bad. + */ + virtual StatusCode assign (const std::string& sgkey) override; // /** @@ -92,6 +113,27 @@ public: // * Overridden here to return the CLID for @c T instead of @c topbase_t. // */ // CLID clid() const; + + + /** + * @brief If this object is used as a property, then this should be called + * during the initialize phase. It will fail if the requested + * StoreGate service cannot be found or if the key is blank. + * @param used If false, then this handle is not to be used. + * Instead of normal initialization, the key will be cleared. + */ + StatusCode initialize (bool used = true); + + + /** + * @brief Return the handle key for the container. + */ + const ReadHandleKey<T>& contHandleKey() const; + + +private: + /// The container handle. + ReadHandleKey<T> m_contHandleKey; }; diff --git a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandleKey.icc b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandleKey.icc index 457db4d3ade831a0fbe13d13f07c9f4228d61c54..c71902c5e2ec724c26ccd488a46db86be5ebc4c9 100644 --- a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandleKey.icc +++ b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadDecorHandleKey.icc @@ -10,26 +10,30 @@ * ReadDecorHandle is made. */ +#include <AsgDataHandles/DecorKeyHelpers.h> + namespace SG { -// /** -// * @brief Constructor. -// * @param key The StoreGate key for the object. -// * @param storeName Name to use for the store, if it's not encoded in sgkey. -// * -// * The provided key may actually start with the name of the store, -// * separated by a "+": "MyStore+Obj". If no "+" is present -// * the store named by @c storeName is used. -// */ -// template <class T> -// inline -// ReadDecorHandleKey<T>::ReadDecorHandleKey (const std::string& key /*= ""*/, -// const std::string& storeName /*= StoreID::storeName(StoreID::EVENT_STORE)*/) -// : Base (ClassID_traits<topbase_t>::ID(), key, storeName) -// { -// } +/** + * @brief Constructor. + * @param key The StoreGate key for the object. + * @param storeName Name to use for the store, if it's not encoded in sgkey. + * + * The provided key may actually start with the name of the store, + * separated by a "+": "MyStore+Obj". If no "+" is present + * the store named by @c storeName is used. + */ +template <class T> +inline +ReadDecorHandleKey<T>::ReadDecorHandleKey (const std::string& key /*= ""*/) + // const std::string& storeName /*= StoreID::storeName(StoreID::EVENT_STORE)*/) + // : Base (ClassID_traits<topbase_t>::ID(), key, storeName), + : Base (key), + m_contHandleKey (contKeyFromKey (key)/*, storeName*/) +{ +} /** @@ -52,8 +56,48 @@ ReadDecorHandleKey<T>::ReadDecorHandleKey( OWNER* owner, const std::string& name, const K& key /*={}*/, const std::string& doc /*=""*/) - : Base (owner, name, key, doc) + : Base (key), + m_contHandleKey (contKeyFromKey (key)/*, StoreID::storeName(StoreID::EVENT_STORE) */) +{ + owner->declareProperty(name, *this, doc); +} + + +/** + * @brief Change the key of the object to which we're referring. + * @param sgkey The StoreGate key for the object. + * + * The provided key may actually start with the name of the store, + * separated by a "+": "MyStore+Obj". If no "+" is present, + * the store is not changed. + */ +template <class T> +ReadDecorHandleKey<T>& +ReadDecorHandleKey<T>::operator= (const std::string& sgkey) { + m_contHandleKey = contKeyFromKey (sgkey); + Base::operator= (sgkey); + return *this; +} + + +/** + * @brief Change the key of the object to which we're referring. + * @param sgkey The StoreGate key for the object. + * + * The provided key may actually start with the name of the store, + * separated by a "+": "MyStore+Obj". If no "+" is present + * the store is not changed. A key name that starts with a "+" + * is interpreted as a hierarchical key name, not an empty store name. + * + * Returns failure the key string format is bad. + */ +template <class T> +StatusCode ReadDecorHandleKey<T>::assign (const std::string& sgkey) +{ + if (m_contHandleKey.assign (contKeyFromKey (sgkey)).isFailure()) + return StatusCode::FAILURE; + return Base::assign (sgkey); } @@ -70,4 +114,31 @@ ReadDecorHandleKey<T>::ReadDecorHandleKey( OWNER* owner, // } +/** + * @brief If this object is used as a property, then this should be called + * during the initialize phase. It will fail if the requested + * StoreGate service cannot be found or if the key is blank. + * + * @param used If false, then this handle is not to be used. + * Instead of normal initialization, the key will be cleared. + */ +template <class T> +StatusCode ReadDecorHandleKey<T>::initialize (bool used /*= true*/) +{ + if (m_contHandleKey.initialize (used).isFailure()) + return StatusCode::FAILURE; + return Base::initialize (used); +} + + +/** + * @brief Return the handle key for the container. + */ +template <class T> +const ReadHandleKey<T>& ReadDecorHandleKey<T>::contHandleKey() const +{ + return m_contHandleKey; +} + + } // namespace SG diff --git a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadHandleKey.icc b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadHandleKey.icc index be2422d1c43bb5f97634e22a8596ce3edf73f8d0..9878c897f3e6dc23ddda6f9a3145de5064a2bec5 100644 --- a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadHandleKey.icc +++ b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/ReadHandleKey.icc @@ -31,19 +31,19 @@ ReadHandleKey<T>::ReadHandleKey (const std::string& key) } -// /** -// * @brief Auto-declaring Property constructor. -// * @param owner Owning component. -// * @param name Name of the Property. -// * @param key Default StoreGate key for the object. -// * @param doc Documentation string. -// * -// * Will associate the named Property with this RHK via declareProperty. -// * -// * The provided key may actually start with the name of the store, -// * separated by a "+": "MyStore+Obj". If no "+" is present -// * the store named by @c storeName is used. -// */ +/** + * @brief Auto-declaring Property constructor. + * @param owner Owning component. + * @param name Name of the Property. + * @param key Default StoreGate key for the object. + * @param doc Documentation string. + * + * Will associate the named Property with this RHK via declareProperty. + * + * The provided key may actually start with the name of the store, + * separated by a "+": "MyStore+Obj". If no "+" is present + * the store named by @c storeName is used. + */ template <class T> template <class OWNER, class K> inline diff --git a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandle.h b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandle.h index 7e113d0899fd600a01cc541251d9205b7bca2444..b02aa5f2189529d5e3208981f5231adb4f91017f 100644 --- a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandle.h +++ b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandle.h @@ -68,19 +68,20 @@ public: explicit WriteDecorHandle (const WriteDecorHandleKey<T>& key); -// /** -// * @brief Constructor from a ReadDecorHandleKey and an explicit event context. -// * @param key The key object holding the clid/key. -// * @param ctx The event context. -// * -// * This will raise an exception if the StoreGate key is blank, -// * or if the event store cannot be found. -// * -// * If the default event store has been requested, then the thread-specific -// * store from the event context will be used. -// */ -// explicit WriteDecorHandle (const WriteDecorHandleKey<T>& key, -// const EventContext& ctx); + /** + * @brief Constructor from a ReadDecorHandleKey and an explicit event context. + * @param key The key object holding the clid/key. + * @param ctx The event context. + * + * This will raise an exception if the StoreGate key is blank, + * or if the event store cannot be found. + * + * If the default event store has been requested, then the thread-specific + * store from the event context will be used. + */ + explicit WriteDecorHandle (const WriteDecorHandleKey<T>& key, + const EventContext& ctx); + // /** // * @brief Copy constructor. @@ -112,15 +113,15 @@ public: // WriteDecorHandle& operator= (WriteDecorHandle&& rhs); -// /** -// * @brief Is the referenced container present in SG? -// * -// * Note that this tests for the presence of the _container_, -// * not for the decoration. -// * -// * Const method; the handle does not change as a result of this. -// */ -// bool isPresent() const; + /** + * @brief Is the referenced container present in SG? + * + * Note that this tests for the presence of the _container_, + * not for the decoration. + * + * Const method; the handle does not change as a result of this. + */ + bool isPresent() const; // /** @@ -160,11 +161,11 @@ public: // getDecorationArray(); -// /** -// * @brief Test to see if this variable exists in the store, -// * for the referenced object. -// */ -// bool isAvailable(); + /** + * @brief Test to see if this variable exists in the store, + * for the referenced object. + */ + bool isAvailable(); // /** @@ -172,7 +173,19 @@ public: // */ // SG::auxid_t auxid() const; - + + // /** + // * @brief Return the mode (read/write/update) for this handle. + // */ + // Gaudi::DataHandle::Mode mode() const; + + + /** + * @brief Return the name of the decoration alias (CONT.DECOR). + */ + std::string decorKey() const; + + // private: // /** // * @brief Retrieve an object from StoreGate. @@ -184,22 +197,22 @@ public: // virtual void* typeless_dataPointer_impl (bool quiet) override; -// /** -// * @brief Test to see if this variable exists in the store, -// * for the referenced object. -// * Specialization for the case of a standalone object -// * (@c T derives from @c SG::AuxElement). -// */ -// bool isAvailable (std::true_type); + /** + * @brief Test to see if this variable exists in the store, + * for the referenced object. + * Specialization for the case of a standalone object + * (@c T derives from @c SG::AuxElement). + */ + bool isAvailable (std::true_type); -// /** -// * @brief Test to see if this variable exists in the store, -// * for the referenced object. -// * Specialization for the case of a container -// * (@c T does not derive from @c SG::AuxElement). -// */ -// bool isAvailable (std::false_type); + /** + * @brief Test to see if this variable exists in the store, + * for the referenced object. + * Specialization for the case of a container + * (@c T does not derive from @c SG::AuxElement). + */ + bool isAvailable (std::false_type); // /** @@ -228,9 +241,8 @@ public: // const SG::AuxVectorData* vectorData(); -// /// Handle for reading the referenced object using its original name -// /// (not the alias). -// SG::ReadHandle<T> m_contHandle; + /// Name of the decoration alias: CONT.DECOR. + std::string m_decorKey; /// Accessor for the aux data item. diff --git a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandle.icc b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandle.icc index 485db240290c53750c148433c409e5d94d2faf8b..f54aa1ecba57ba1ee46e410ae3b0849f2c74edf9 100644 --- a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandle.icc +++ b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandle.icc @@ -24,34 +24,34 @@ namespace SG { */ template <class T, class D> WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandleKey<T>& key) - : Base (key, nullptr), - // m_contHandle (key.contHandleKey()), + : Base (key.contHandleKey(), nullptr), + m_decorKey (key.key()), m_acc (SG::decorKeyFromKey (key.key())) // m_madeAlias (false) { } -// /** -// * @brief Constructor from a ReadDecorHandleKey and an explicit event context. -// * @param key The key object holding the clid/key. -// * @param ctx The event context. -// * -// * This will raise an exception if the StoreGate key is blank, -// * or if the event store cannot be found. -// * -// * If the default event store has been requested, then the thread-specific -// * store from the event context will be used. -// */ -// template <class T, class D> -// WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandleKey<T>& key, -// const EventContext& ctx) -// : Base (key, &ctx), -// m_contHandle (key.contHandleKey(), ctx), -// m_acc (SG::decorKeyFromKey (key.key())), -// m_madeAlias (false) -// { -// } +/** + * @brief Constructor from a ReadDecorHandleKey and an explicit event context. + * @param key The key object holding the clid/key. + * @param ctx The event context. + * + * This will raise an exception if the StoreGate key is blank, + * or if the event store cannot be found. + * + * If the default event store has been requested, then the thread-specific + * store from the event context will be used. + */ +template <class T, class D> +WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandleKey<T>& key, + const EventContext& ctx) + : Base (key.contHandleKey(), &ctx), + m_decorKey (key.key()), + m_acc (SG::decorKeyFromKey (key.key())) + // m_madeAlias (false) +{ +} // /** @@ -60,7 +60,7 @@ WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandleKey<T>& key) // template <class T, class D> // WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandle& rhs) // : Base (rhs), -// m_contHandle (rhs.m_contHandle), +// m_decorKey (rhs.m_decorKey), // m_acc (rhs.m_acc), // m_madeAlias (rhs.m_madeAlias) // { @@ -73,7 +73,7 @@ WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandleKey<T>& key) // template <class T, class D> // WriteDecorHandle<T, D>::WriteDecorHandle (WriteDecorHandle&& rhs) // : Base (std::move (rhs)), -// m_contHandle (std::move (rhs.m_contHandle)), +// m_decorKey (std::move (rhs.m_decorKey)), // m_acc (std::move (rhs.m_acc)), // m_madeAlias (rhs.m_madeAlias) // { @@ -107,7 +107,7 @@ WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandleKey<T>& key) // if (this != &rhs) { // *static_cast<Base*>(this) = rhs; // m_acc = rhs.m_acc; -// m_contHandle = rhs.m_contHandle; +// m_decorKey = rhs.m_decorKey; // m_madeAlias = rhs.m_madeAlias; // } // return *this; @@ -123,7 +123,7 @@ WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandleKey<T>& key) // if (this != &rhs) { // *static_cast<Base*>(this) = std::move (rhs); // m_acc = std::move (rhs.m_acc); -// m_contHandle = std::move (rhs.m_contHandle); +// m_decorKey = std::move (rhs.m_decorKey); // m_madeAlias = rhs.m_madeAlias; // rhs.m_madeAlias = false; // } @@ -131,19 +131,19 @@ WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandleKey<T>& key) // } -// /** -// * @brief Is the referenced container present in SG? -// * -// * Note that this tests for the presence of the _container_, -// * not for the decoration. -// * -// * Const method; the handle does not change as a result of this. -// */ -// template <class T, class D> -// bool WriteDecorHandle<T, D>::isPresent() const -// { -// return m_contHandle.isPresent(); -// } +/** + * @brief Is the referenced container present in SG? + * + * Note that this tests for the presence of the _container_, + * not for the decoration. + * + * Const method; the handle does not change as a result of this. + */ +template <class T, class D> +bool WriteDecorHandle<T, D>::isPresent() const +{ + return Base::isPresent(); +} // /** @@ -159,8 +159,6 @@ WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandleKey<T>& key) // StatusCode WriteDecorHandle<T, D>::setProxyDict (IProxyDict* store) // { // m_madeAlias = false; -// if (m_contHandle.setProxyDict (store).isFailure()) -// return StatusCode::FAILURE; // return Base::setProxyDict (store); // } @@ -207,72 +205,96 @@ WriteDecorHandle<T, D>::operator() (const AuxElement& e) // } -// /** -// * @brief Test to see if this variable exists in the store, -// * for the referenced object. -// * Specialization for the case of a standalone object -// * (@c T derives from @c SG::AuxElement). -// */ -// template <class T, class D> -// inline -// bool WriteDecorHandle<T, D>::isAvailable (std::true_type) -// { -// if (this->m_ptr) { -// const SG::AuxVectorData* obj = static_cast<const T*>(this->m_ptr)->container(); -// if (obj) { -// return obj->isAvailable (m_acc.auxid()); -// } -// } +/** + * @brief Test to see if this variable exists in the store, + * for the referenced object. + * Specialization for the case of a standalone object + * (@c T derives from @c SG::AuxElement). + */ +template <class T, class D> +inline +bool WriteDecorHandle<T, D>::isAvailable (std::true_type) +{ + const T* ptr = this->ptr(); + if (ptr) { + const SG::AuxVectorData* obj = ptr->container(); + if (obj) { + return obj->isAvailable (m_acc.auxid()); + } + } + + return false; +} -// return false; -// } +/** + * @brief Test to see if this variable exists in the store, + * for the referenced object. + * Specialization for the case of a container + * (@c T does not derive from @c SG::AuxElement). + */ +template <class T, class D> +inline +bool WriteDecorHandle<T, D>::isAvailable (std::false_type) +{ + const T* ptr = this->ptr(); + if (ptr) { + return ptr->isAvailable (m_acc.auxid()); + } -// /** -// * @brief Test to see if this variable exists in the store, -// * for the referenced object. -// * Specialization for the case of a container -// * (@c T does not derive from @c SG::AuxElement). -// */ -// template <class T, class D> -// inline -// bool WriteDecorHandle<T, D>::isAvailable (std::false_type) -// { -// if (this->m_ptr) { -// return static_cast<const T*>(this->m_ptr)->isAvailable (m_acc.auxid()); -// } + return false; +} -// return false; -// } + +/** + * @brief Test to see if this variable exists in the store, + * for the referenced object. + */ +template <class T, class D> +inline +bool WriteDecorHandle<T, D>::isAvailable() +{ + // if (!this->m_ptr) { + // ReadHandle<T>::typeless_dataPointer_impl (true); + // } + // We can't just use vectorData() because that will create the decoration + // as a side effect. + return isAvailable (typename std::is_base_of<SG::AuxElement, T>::type()); +} // /** -// * @brief Test to see if this variable exists in the store, -// * for the referenced object. +// * @brief Return the aux id for this variable. // */ // template <class T, class D> -// inline -// bool WriteDecorHandle<T, D>::isAvailable() +// SG::auxid_t WriteDecorHandle<T, D>::auxid() const // { -// if (!this->m_ptr) { -// ReadHandle<T>::typeless_dataPointer_impl (true); -// } -// // We can't just use vectorData() because that will create the decoration -// // as a side effect. -// return isAvailable (typename std::is_base_of<SG::AuxElement, T>::type()); +// return m_acc.auxid(); // } // /** -// * @brief Return the aux id for this variable. +// * @brief Return the mode (read/write/update) for this handle. // */ // template <class T, class D> -// SG::auxid_t WriteDecorHandle<T, D>::auxid() const +// inline +// Gaudi::DataHandle::Mode WriteDecorHandle<T, D>::mode() const // { -// return m_acc.auxid(); +// return Gaudi::DataHandle::Writer; // } +/** + * @brief Return the name of the decoration alias (CONT.DECOR). + */ +template <class T, class D> +inline +std::string WriteDecorHandle<T, D>::decorKey() const +{ + return m_decorKey; +} + + // /** // * @brief Retrieve an object from StoreGate. // * @param quiet If true, suppress failure messages. @@ -285,11 +307,14 @@ WriteDecorHandle<T, D>::operator() (const AuxElement& e) // { // if (this->m_ptr && this->m_madeAlias) // return this->m_ptr; -// if (m_contHandle.alias (WriteHandleKey<T> (this->key())).isFailure()) -// return nullptr; // if (!this->m_ptr) { // ReadHandle<T>::typeless_dataPointer_impl (quiet); // } +// if (!this->m_ptr) { +// return nullptr; +// } +// if (this->alias (WriteHandleKey<T> (this->m_decorKey)).isFailure()) +// return nullptr; // // Important to call the base class method above before calling vectorData; // // otherwise, we'll get an infinite recursion. // // Also don't call getDecorationArray if the container is empty. diff --git a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandleKey.h b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandleKey.h index 2f3bf2a7e96dd9b0cb2c2811a35abde11dd6b176..ec654aea611fb2c78d0dd449313e3ab97a781a60 100644 --- a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandleKey.h +++ b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandleKey.h @@ -21,8 +21,8 @@ #include "AsgDataHandles/DecorKeyHelpers.h" +#include "AsgDataHandles/ReadHandleKey.h" #include "AsgDataHandles/WriteHandleKey.h" -// #include "StoreGate/ReadHandleKey.h" // class AthAlgorithm; @@ -81,10 +81,10 @@ public: * the store named by @c storeName is used. */ template <class OWNER, class K> - WriteDecorHandleKey( OWNER* owner, - const std::string& name, - const K& key = {}, - const std::string& doc = ""); + WriteDecorHandleKey (OWNER* owner, + const std::string& name, + const K& key = {}, + const std::string& doc = ""); /** @@ -98,34 +98,34 @@ public: WriteDecorHandleKey& operator= (const std::string& sgkey); -// /** -// * @brief Change the key of the object to which we're referring. -// * @param sgkey The StoreGate key for the object. -// * -// * The provided key may actually start with the name of the store, -// * separated by a "+": "MyStore+Obj". If no "+" is present -// * the store is not changed. A key name that starts with a slash -// * is interpreted as a hierarchical key name, not an empty store name. -// * -// * Returns failure the key string format is bad. -// */ -// virtual StatusCode assign (const std::string& sgkey) override; + /** + * @brief Change the key of the object to which we're referring. + * @param sgkey The StoreGate key for the object. + * + * The provided key may actually start with the name of the store, + * separated by a "+": "MyStore+Obj". If no "+" is present + * the store is not changed. A key name that starts with a slash + * is interpreted as a hierarchical key name, not an empty store name. + * + * Returns failure the key string format is bad. + */ + virtual StatusCode assign (const std::string& sgkey) override; -// /** -// * @brief If this object is used as a property, then this should be called -// * during the initialize phase. It will fail if the requested -// * StoreGate service cannot be found or if the key is blank. -// * @param used If false, then this handle is not to be used. -// * Instead of normal initialization, the key will be cleared. -// */ -// StatusCode initialize (bool used = true); + /** + * @brief If this object is used as a property, then this should be called + * during the initialize phase. It will fail if the requested + * StoreGate service cannot be found or if the key is blank. + * @param used If false, then this handle is not to be used. + * Instead of normal initialization, the key will be cleared. + */ + StatusCode initialize (bool used = true); -// /** -// * @brief Return the handle key for the container. -// */ -// const ReadHandleKey<T>& contHandleKey() const; + /** + * @brief Return the handle key for the container. + */ + const ReadHandleKey<T>& contHandleKey() const; // private: @@ -141,8 +141,8 @@ public: // ReadHandleKey<T>& contHandleKey_nc(); -// /// The container handle. -// ReadHandleKey<T> m_contHandleKey; + /// The container handle. + ReadHandleKey<T> m_contHandleKey; }; diff --git a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandleKey.icc b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandleKey.icc index 3195daa225c4dbb8d1394352fd2b5a17d5595f7f..20a8004d24311509fec72481cf2df0f32ed2083e 100644 --- a/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandleKey.icc +++ b/Control/AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandleKey.icc @@ -11,7 +11,7 @@ */ -// #include "StoreGate/tools/DecorKeyHelpers.h" +#include "AsgDataHandles/DecorKeyHelpers.h" // #include "GaudiKernel/IDataHandleHolder.h" @@ -43,8 +43,8 @@ namespace SG { template <class T> WriteDecorHandleKey<T>::WriteDecorHandleKey (const std::string& key /*= ""*/) : // const std::string& storeName /*= "StoreGateSvc"*/) : - Base (key/*, storeName*/) - // m_contHandleKey (contKeyFromKey (key)/*, storeName*/) + Base (key/*, storeName*/), + m_contHandleKey (contKeyFromKey (key)/*, storeName*/) { } @@ -69,9 +69,10 @@ WriteDecorHandleKey<T>::WriteDecorHandleKey( OWNER* owner, const std::string& name, const K& key /*={}*/, const std::string& doc /*=""*/) - : Base (owner, name, key, doc) - // m_contHandleKey (contKeyFromKey (key), StoreID::storeName(StoreID::EVENT_STORE) ) + : Base (key), + m_contHandleKey (contKeyFromKey (key)/*, StoreID::storeName(StoreID::EVENT_STORE) */) { + owner->declareProperty(name, *this, doc); } @@ -87,58 +88,58 @@ template <class T> WriteDecorHandleKey<T>& WriteDecorHandleKey<T>::operator= (const std::string& sgkey) { - // m_contHandleKey = contKeyFromKey (sgkey); + m_contHandleKey = contKeyFromKey (sgkey); Base::operator= (sgkey); return *this; } -// /** -// * @brief Change the key of the object to which we're referring. -// * @param sgkey The StoreGate key for the object. -// * -// * The provided key may actually start with the name of the store, -// * separated by a "+": "MyStore+Obj". If no "+" is present -// * the store is not changed. A key name that starts with a "+" -// * is interpreted as a hierarchical key name, not an empty store name. -// * -// * Returns failure the key string format is bad. -// */ -// template <class T> -// StatusCode WriteDecorHandleKey<T>::assign (const std::string& sgkey) -// { -// if (m_contHandleKey.assign (contKeyFromKey (sgkey)).isFailure()) -// return StatusCode::FAILURE; -// return Base::assign (sgkey); -// } +/** + * @brief Change the key of the object to which we're referring. + * @param sgkey The StoreGate key for the object. + * + * The provided key may actually start with the name of the store, + * separated by a "+": "MyStore+Obj". If no "+" is present + * the store is not changed. A key name that starts with a "+" + * is interpreted as a hierarchical key name, not an empty store name. + * + * Returns failure the key string format is bad. + */ +template <class T> +StatusCode WriteDecorHandleKey<T>::assign (const std::string& sgkey) +{ + if (m_contHandleKey.assign (contKeyFromKey (sgkey)).isFailure()) + return StatusCode::FAILURE; + return Base::assign (sgkey); +} -// /** -// * @brief If this object is used as a property, then this should be called -// * during the initialize phase. It will fail if the requested -// * StoreGate service cannot be found or if the key is blank. -// * -// * @param used If false, then this handle is not to be used. -// * Instead of normal initialization, the key will be cleared. -// */ -// template <class T> -// StatusCode WriteDecorHandleKey<T>::initialize (bool used /*= true*/) -// { -// detail::registerWriteDecorHandleKey (this->owner(), m_contHandleKey.fullKey()); -// if (m_contHandleKey.initialize (used).isFailure()) -// return StatusCode::FAILURE; -// return Base::initialize (used); -// } +/** + * @brief If this object is used as a property, then this should be called + * during the initialize phase. It will fail if the requested + * StoreGate service cannot be found or if the key is blank. + * + * @param used If false, then this handle is not to be used. + * Instead of normal initialization, the key will be cleared. + */ +template <class T> +StatusCode WriteDecorHandleKey<T>::initialize (bool used /*= true*/) +{ + // detail::registerWriteDecorHandleKey (this->owner(), m_contHandleKey.fullKey()); + if (m_contHandleKey.initialize (used).isFailure()) + return StatusCode::FAILURE; + return Base::initialize (used); +} -// /** -// * @brief Return the handle key for the container. -// */ -// template <class T> -// const ReadHandleKey<T>& WriteDecorHandleKey<T>::contHandleKey() const -// { -// return m_contHandleKey; -// } +/** + * @brief Return the handle key for the container. + */ +template <class T> +const ReadHandleKey<T>& WriteDecorHandleKey<T>::contHandleKey() const +{ + return m_contHandleKey; +} // /** diff --git a/Control/AthToolSupport/AsgDataHandles/CMakeLists.txt b/Control/AthToolSupport/AsgDataHandles/CMakeLists.txt index 704ebcb25f506d05cdb4a121a82cfc3a4e9881de..893eb01e1fc75c543b357e819af0c0df8ee6b238 100644 --- a/Control/AthToolSupport/AsgDataHandles/CMakeLists.txt +++ b/Control/AthToolSupport/AsgDataHandles/CMakeLists.txt @@ -19,6 +19,6 @@ atlas_add_library( AsgDataHandlesLib AsgDataHandles/*.h AsgDataHandles/*.icc Root/*.cxx PUBLIC_HEADERS AsgDataHandles PRIVATE_INCLUDE_DIRS - LINK_LIBRARIES AsgMessagingLib xAODRootAccessInterfaces ) + LINK_LIBRARIES AthContainers AsgMessagingLib xAODRootAccessInterfaces ) endif() diff --git a/Control/AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx b/Control/AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx index 9ad4a6667f0f0158c8a1796c37731a785fc957aa..a32781e4c174a7c66a896292429d37096e65513f 100644 --- a/Control/AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx +++ b/Control/AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx @@ -67,7 +67,9 @@ VarHandleKey::VarHandleKey (const std::string& sgkey) */ VarHandleKey& VarHandleKey::operator= (const std::string& sgkey) { - m_sgKey = sgkey; + if (assign (sgkey).isFailure ()) { + throw std::runtime_error (std::string("Could not assign VarHandleKey with key ") + sgkey); + } return *this; } diff --git a/Control/AthToolSupport/AsgExampleTools/AsgExampleTools/DataHandleTestTool.h b/Control/AthToolSupport/AsgExampleTools/AsgExampleTools/DataHandleTestTool.h index e851fa666e9b91070b6aec99cc37ef9a0f489c8c..6595cbaf3b563c2e9196e2b8cbb5050005f08118 100644 --- a/Control/AthToolSupport/AsgExampleTools/AsgExampleTools/DataHandleTestTool.h +++ b/Control/AthToolSupport/AsgExampleTools/AsgExampleTools/DataHandleTestTool.h @@ -53,16 +53,20 @@ namespace asg public: #ifndef SIMULATIONBASE SG::ReadHandleKey<xAOD::MuonContainer> m_readKey {this, "readKey", "Muons", "regular read key"}; + SG::ReadHandleKey<xAOD::MuonContainer> m_readKeyEmpty {this, "readKeyEmpty", "", "regular read key (empty by default)"}; SG::ReadDecorHandleKey<xAOD::MuonContainer> m_readDecorKey {this, "readDecorKey", "Muons.pt", "read decor key"}; + SG::ReadDecorHandleKey<xAOD::MuonContainer> m_readDecorKeyEmpty {this, "readDecorKeyEmpty", "", "read decor key (empty by default)"}; SG::ReadHandleKeyArray<xAOD::MuonContainer> m_readKeyArray {this, "readKeyArray", {}, "array read key"}; SG::WriteHandleKey<xAOD::MuonContainer> m_writeKey {this, "writeKey", "", "regular write key"}; SG::WriteDecorHandleKey<xAOD::MuonContainer> m_writeDecorKey {this, "writeDecorKey", "", "write decor key"}; + SG::WriteDecorHandleKey<xAOD::MuonContainer> m_writeDecorKeyExisting {this, "writeDecorKeyExisting", "", "write decor key (existing)"}; #endif bool m_readFailure {false}; bool m_readArray {false}; bool m_readDecorFailure {false}; std::string m_doWriteName; std::string m_doWriteDecorName; + std::string m_doWriteDecorNameExisting; }; } diff --git a/Control/AthToolSupport/AsgExampleTools/CMakeLists.txt b/Control/AthToolSupport/AsgExampleTools/CMakeLists.txt index 96e3f8515f2ee86df5d1de93d6455e6ca0cf38e9..d1b02221d1c7c46281bcac73d46895db07964b99 100644 --- a/Control/AthToolSupport/AsgExampleTools/CMakeLists.txt +++ b/Control/AthToolSupport/AsgExampleTools/CMakeLists.txt @@ -98,6 +98,14 @@ if (NOT SIMULATIONBASE) set (extra_libs ) endif() + if( XAOD_STANDALONE ) + atlas_add_test( gt_DataHandlesUnitTest + SOURCES test/gt_DataHandlesUnitTest.cxx + INCLUDE_DIRS ${GTEST_INCLUDE_DIRS} + LINK_LIBRARIES ${GTEST_LIBRARIES} AsgDataHandlesLib AsgTestingLib xAODRootAccess) + set_tests_properties (AsgExampleTools_gt_DataHandlesUnitTest_ctest PROPERTIES LABELS "AsgDataHandles;AsgExampleTools" ) + endif() + atlas_add_test( gt_DataHandlesTest SOURCES test/gt_DataHandlesTest.cxx INCLUDE_DIRS ${GTEST_INCLUDE_DIRS} diff --git a/Control/AthToolSupport/AsgExampleTools/Root/DataHandleTestTool.cxx b/Control/AthToolSupport/AsgExampleTools/Root/DataHandleTestTool.cxx index 4248f17db322e26e05065a522b60f4380d53d4b6..452d872ba95c3dd0db151353eb0b29dcb4a4b522 100644 --- a/Control/AthToolSupport/AsgExampleTools/Root/DataHandleTestTool.cxx +++ b/Control/AthToolSupport/AsgExampleTools/Root/DataHandleTestTool.cxx @@ -39,6 +39,7 @@ namespace asg declareProperty ("readArray", m_readArray, "whether to read from the array"); declareProperty ("doWriteName", m_doWriteName, "if we should write, the name we expect to write to"); declareProperty ("doWriteDecorName", m_doWriteDecorName, "if we should write a decoration, the name we expect to write to"); + declareProperty ("doWriteDecorNameExisting", m_doWriteDecorNameExisting, "if we should try to overwrite an existing decoration, the name we expect to write to"); } @@ -55,12 +56,13 @@ namespace asg { #ifndef SIMULATIONBASE ANA_CHECK (m_readKey.initialize ()); + ANA_CHECK (m_readKeyEmpty.initialize (!m_readKeyEmpty.empty ())); ANA_CHECK (m_readDecorKey.initialize ()); - if (!m_writeKey.empty()) - ANA_CHECK (m_writeKey.initialize ()); + ANA_CHECK (m_readDecorKeyEmpty.initialize (!m_readDecorKeyEmpty.empty ())); + ANA_CHECK (m_writeKey.initialize (!m_writeKey.empty())); ANA_CHECK (m_readKeyArray.initialize()); - if (!m_writeDecorKey.empty()) - ANA_CHECK (m_writeDecorKey.initialize ()); + ANA_CHECK (m_writeDecorKey.initialize (!m_writeDecorKey.empty ())); + ANA_CHECK (m_writeDecorKeyExisting.initialize (!m_writeDecorKeyExisting.empty ())); #endif return StatusCode::SUCCESS; } @@ -92,9 +94,13 @@ namespace asg SG::ReadDecorHandle<xAOD::MuonContainer,float> readDecorHandle (m_readDecorKey); if (m_readDecorFailure == true) { + EXPECT_TRUE(readDecorHandle.isPresent()); + EXPECT_FALSE(readDecorHandle.isAvailable()); EXPECT_ANY_THROW (readDecorHandle (*testMuon)); } else { + EXPECT_TRUE(readDecorHandle.isPresent()); + EXPECT_TRUE(readDecorHandle.isAvailable()); SG::AuxElement::ConstAccessor<float> acc ("pt"); EXPECT_EQ (acc (*testMuon), readDecorHandle (*testMuon)); } @@ -128,10 +134,19 @@ namespace asg if (!m_doWriteDecorName.empty()) { auto writeDecorHandle = SG::makeHandle<unsigned> (m_writeDecorKey); + EXPECT_TRUE(writeDecorHandle.isPresent()); + EXPECT_FALSE(writeDecorHandle.isAvailable()); writeDecorHandle (*(*muonsStore)[0]) = 42u; SG::AuxElement::ConstAccessor<unsigned> acc (m_doWriteDecorName); EXPECT_EQ (42u, acc (*(*muonsStore)[0])); } + + if (!m_doWriteDecorNameExisting.empty()) + { + auto writeDecorHandleExisting = SG::makeHandle<float> (m_writeDecorKeyExisting); + EXPECT_TRUE(writeDecorHandleExisting.isPresent()); + EXPECT_TRUE(writeDecorHandleExisting.isAvailable()); + } #endif } } diff --git a/Control/AthToolSupport/AsgExampleTools/test/gt_DataHandlesTest.cxx b/Control/AthToolSupport/AsgExampleTools/test/gt_DataHandlesTest.cxx index b95079f43ba89d70797e43101ad6479ddeae06b1..9302fdd383b3fe9e874a4996ca524df36d9af5d7 100644 --- a/Control/AthToolSupport/AsgExampleTools/test/gt_DataHandlesTest.cxx +++ b/Control/AthToolSupport/AsgExampleTools/test/gt_DataHandlesTest.cxx @@ -14,6 +14,7 @@ #include <AsgMessaging/MessageCheck.h> #include <AsgTesting/UnitTest.h> #include <AsgExampleTools/IDataHandleTestTool.h> +#include <TClass.h> #include <TFile.h> #include <cmath> #include <gtest/gtest.h> @@ -40,6 +41,10 @@ namespace asg { static void SetUpTestCase () { + // Access the dictionary + ASSERT_NE (TClass::GetClass ("xAOD::MuonContainer"), nullptr); + ASSERT_NE (TClass::GetClass ("asg::DataHandleTestTool"), nullptr); + const char *test_file = getenv ("ASG_TEST_FILE_MC"); ASSERT_NE (nullptr, test_file); file.reset (TFile::Open (test_file, "READ")); @@ -149,6 +154,28 @@ namespace asg ASSERT_SUCCESS (config.makeTool (tool, cleanup)); tool->runTest (); } + + + + // do an existing write decor handle test + TEST_F (DataHandlesTest, write_decor_handle_existing) + { + config.setPropertyFromString ("writeDecorKeyExisting", "Muons.pt"); + config.setPropertyFromString ("doWriteDecorNameExisting", "pt"); + ASSERT_SUCCESS (config.makeTool (tool, cleanup)); + tool->runTest (); + } + + + + // empty initial handles + TEST_F (DataHandlesTest, empty_initial_handles) + { + config.setPropertyFromString ("readKeyEmpty", "Muons"); + config.setPropertyFromString ("readDecorKeyEmpty", "Muons.eta"); + ASSERT_SUCCESS (config.makeTool (tool, cleanup)); + tool->runTest (); + } } ATLAS_GOOGLE_TEST_MAIN diff --git a/Control/AthToolSupport/AsgExampleTools/test/gt_DataHandlesUnitTest.cxx b/Control/AthToolSupport/AsgExampleTools/test/gt_DataHandlesUnitTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8951cc9e64f97bbbfcd3e0ac74967f53e18d1215 --- /dev/null +++ b/Control/AthToolSupport/AsgExampleTools/test/gt_DataHandlesUnitTest.cxx @@ -0,0 +1,161 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include <AsgDataHandles/ReadDecorHandle.h> +#include <AsgDataHandles/ReadDecorHandleKey.h> +#include <AsgDataHandles/ReadHandle.h> +#include <AsgDataHandles/ReadHandleKey.h> +#include <AsgDataHandles/WriteDecorHandle.h> +#include <AsgDataHandles/WriteDecorHandleKey.h> +#include <AsgDataHandles/WriteHandle.h> +#include <AsgDataHandles/WriteHandleKey.h> +#include <AsgTesting/UnitTest.h> +#include <AsgTools/CurrentContext.h> +#include <xAODCore/CLASS_DEF.h> +#include <xAODRootAccess/TEvent.h> +#include <gtest/gtest.h> + + +class MyObj +{ +public: + MyObj(int x=0) : x(x) {} + int x; +}; +CLASS_DEF (MyObj, 293847295, 1) + + +namespace asg +{ + struct DataHandlesUnitTest : public ::testing::Test + { + virtual void SetUp () override + { + } + + xAOD::TEvent event; + }; + + // ReadHandle + TEST_F (DataHandlesUnitTest, ReadHandle) + { + SG::ReadHandleKey<MyObj> k1 ("aaa"); + // ASSERT_EQ (k1.clid(), 293847295); + ASSERT_EQ (k1.key(), "aaa"); + ASSERT_SUCCESS (k1.initialize()); + + k1 = "aab"; + // ASSERT_EQ (k1.clid(), 293847295); + ASSERT_EQ (k1.key(), "aab"); + + SG::ReadHandleKey<MyObj> k2 ("asd"); + ASSERT_SUCCESS (k2.initialize()); + SG::ReadHandle<MyObj> h2 (k2); + // ASSERT_EQ (h2.clid(), 293847295); + ASSERT_EQ (h2.key(), "asd"); + + const EventContext &ctx3 = Gaudi::Hive::currentContext(); + SG::ReadHandle<MyObj> h3 (k2, ctx3); + // ASSERT_EQ (h3.clid(), 293847295); + ASSERT_EQ (h3.key(), "asd"); + } + + // WriteHandle + TEST_F (DataHandlesUnitTest, WriteHandle) + { + SG::WriteHandleKey<MyObj> k1 ("aaa"); + // ASSERT_EQ (k1.clid(), 293847295); + ASSERT_EQ (k1.key(), "aaa"); + ASSERT_SUCCESS (k1.initialize()); + + k1 = "aab"; + // ASSERT_EQ (k1.clid(), 293847295); + ASSERT_EQ (k1.key(), "aab"); + + SG::WriteHandleKey<MyObj> k2 ("asd"); + ASSERT_SUCCESS (k2.initialize()); + SG::WriteHandle<MyObj> h2 (k2); + // ASSERT_EQ (h2.clid(), 293847295); + ASSERT_EQ (h2.key(), "asd"); + + const EventContext &ctx3 = Gaudi::Hive::currentContext(); + SG::WriteHandle<MyObj> h3 (k2, ctx3); + // ASSERT_EQ (h3.clid(), 293847295); + ASSERT_EQ (h3.key(), "asd"); + } + + + // ReadDecorHandle + TEST_F (DataHandlesUnitTest, ReadDecorHandle) + { + SG::ReadDecorHandleKey<MyObj> k1 ("aaa.dec"); + // ASSERT_EQ (k1.clid(), 293847295); + ASSERT_EQ (k1.key(), "aaa.dec"); + ASSERT_SUCCESS (k1.initialize()); + + // ASSERT_EQ (k1.contHandleKey().clid(), 293847295); + ASSERT_EQ (k1.contHandleKey().key(), "aaa"); + + k1 = "bbb.foo"; + ASSERT_EQ (k1.key(), "bbb.foo"); + ASSERT_EQ (k1.contHandleKey().key(), "bbb"); + + ASSERT_SUCCESS (k1.assign ("ccc.fee")); + ASSERT_EQ (k1.key(), "ccc.fee"); + ASSERT_EQ (k1.contHandleKey().key(), "ccc"); + + SG::ReadDecorHandleKey<MyObj> k2 ("asd.aaa"); + ASSERT_SUCCESS (k2.initialize()); + + SG::ReadDecorHandle<MyObj, int> h1 (k2); + // ASSERT_EQ (h1.clid(), 293847295); + ASSERT_EQ (h1.key(), "asd"); + ASSERT_EQ (h1.decorKey(), "asd.aaa"); + ASSERT_FALSE (h1.isPresent()); + + const EventContext &ctx2 = Gaudi::Hive::currentContext(); + SG::ReadDecorHandle<MyObj, int> h2 (k2, ctx2); + // ASSERT_EQ (h2.clid(), 293847295); + ASSERT_EQ (h2.key(), "asd"); + ASSERT_EQ (h2.decorKey(), "asd.aaa"); + } + + // WriteDecorHandle + TEST_F (DataHandlesUnitTest, WriteDecorHandle) + { + SG::WriteDecorHandleKey<MyObj> k1 ("aaa.dec"); + // ASSERT_EQ (k1.clid(), 293847295); + ASSERT_EQ (k1.key(), "aaa.dec"); + ASSERT_SUCCESS (k1.initialize()); + + // ASSERT_EQ (k1.contHandleKey().clid(), 293847295); + ASSERT_EQ (k1.contHandleKey().key(), "aaa"); + + k1 = "bbb.foo"; + ASSERT_EQ (k1.key(), "bbb.foo"); + ASSERT_EQ (k1.contHandleKey().key(), "bbb"); + + ASSERT_SUCCESS (k1.assign ("ccc.fee")); + ASSERT_EQ (k1.key(), "ccc.fee"); + ASSERT_EQ (k1.contHandleKey().key(), "ccc"); + + SG::WriteDecorHandleKey<MyObj> k2 ("asd.aaa"); + ASSERT_SUCCESS (k2.initialize()); + + SG::WriteDecorHandle<MyObj, int> h1 (k2); + // ASSERT_EQ (h1.clid(), 293847295); + ASSERT_EQ (h1.key(), "asd"); + ASSERT_EQ (h1.decorKey(), "asd.aaa"); + ASSERT_FALSE (h1.isPresent()); + + const EventContext &ctx2 = Gaudi::Hive::currentContext(); + SG::WriteDecorHandle<MyObj, int> h2 (k2, ctx2); + // ASSERT_EQ (h2.clid(), 293847295); + ASSERT_EQ (h2.key(), "asd"); + ASSERT_EQ (h2.decorKey(), "asd.aaa"); + } + +} + +ATLAS_GOOGLE_TEST_MAIN