Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/k4FWCore/DataHandle.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * Copyright (c) 2014-2024 Key4hep-Project.
0003  *
0004  * This file is part of Key4hep.
0005  * See https://key4hep.github.io/key4hep-doc/ for further info.
0006  *
0007  * Licensed under the Apache License, Version 2.0 (the "License");
0008  * you may not use this file except in compliance with the License.
0009  * You may obtain a copy of the License at
0010  *
0011  *     http://www.apache.org/licenses/LICENSE-2.0
0012  *
0013  * Unless required by applicable law or agreed to in writing, software
0014  * distributed under the License is distributed on an "AS IS" BASIS,
0015  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0016  * See the License for the specific language governing permissions and
0017  * limitations under the License.
0018  */
0019 #ifndef K4FWCORE_DATAHANDLE_H
0020 #define K4FWCORE_DATAHANDLE_H
0021 
0022 #include "k4FWCore/DataWrapper.h"
0023 
0024 #include <GaudiKernel/AnyDataWrapper.h>
0025 #include <GaudiKernel/DataObjectHandle.h>
0026 #include <GaudiKernel/ServiceHandle.h>
0027 
0028 #include <memory>
0029 #include <stdexcept>
0030 #include <string>
0031 #include <type_traits>
0032 
0033 namespace k4FWCore {
0034 /**
0035  * Specialisation of the Gaudi DataHandle
0036  * for use with podio collections.
0037  */
0038 template <typename T>
0039 class DataHandle : public DataObjectHandle<DataWrapper<T>> {
0040 public:
0041   friend class Algorithm;
0042   friend class AlgTool;
0043 
0044 public:
0045   DataHandle() = delete;
0046   DataHandle(const DataHandle&) = delete;
0047   DataHandle& operator=(const DataHandle&) = delete;
0048   DataHandle(DataHandle&&) = default;
0049   DataHandle& operator=(DataHandle&&) = default;
0050   ~DataHandle() override;
0051 
0052   DataHandle(const std::string& k, Gaudi::DataHandle::Mode a, IDataHandleHolder* fatherAlg);
0053 
0054   /// Retrieve object from transient data store
0055   const T* get();
0056 
0057   /**
0058    * Register object in transient store
0059    */
0060   void put(T* object);
0061 
0062   T* put(std::unique_ptr<T> object);
0063 
0064   /**
0065    * Create and register object in transient store
0066    */
0067   T* createAndPut();
0068 
0069 private:
0070   ServiceHandle<IDataProviderSvc> m_eds;
0071   T* m_dataPtr{nullptr};
0072 };
0073 
0074 template <typename T>
0075 DataHandle<T>::~DataHandle() {
0076   // release memory allocated for primitive types (see comments in ctor)
0077   if constexpr (std::is_integral_v<T> || std::is_floating_point_v<T>) {
0078     delete m_dataPtr;
0079   }
0080 }
0081 
0082 template <typename T>
0083 DataHandle<T>::DataHandle(const std::string& descriptor, Gaudi::DataHandle::Mode a, IDataHandleHolder* fatherAlg)
0084     : DataObjectHandle<DataWrapper<T>>(descriptor, a, fatherAlg), m_eds("EventDataSvc", "DataHandle") {
0085   if (a == Gaudi::DataHandle::Writer) {
0086     if constexpr (std::is_integral_v<T> || std::is_floating_point_v<T>) {
0087       m_dataPtr = new T();
0088     }
0089   }
0090 }
0091 
0092 /**
0093  * Try to retrieve from the transient store. If the retrieval succeeded and
0094  * this is the first time we retrieve, perform a dynamic cast to the desired
0095  * object. Then finally set the handle as Read.
0096  * If this is not the first time we cast and the cast worked, just use the
0097  * static cast: we do not need the checks of the dynamic cast for every access!
0098  */
0099 template <typename T>
0100 const T* DataHandle<T>::get() {
0101   DataObject* dataObjectp;
0102   auto sc = m_eds->retrieveObject(DataObjectHandle<DataWrapper<T>>::fullKey().key(), dataObjectp);
0103 
0104   if (sc.isFailure()) {
0105     std::string msg("Could not retrieve product " + DataObjectHandle<DataWrapper<T>>::pythonRepr());
0106     throw GaudiException(msg, "wrong product name", StatusCode::FAILURE);
0107   }
0108   bool isGoodType = nullptr != dynamic_cast<DataWrapper<T>*>(dataObjectp);
0109   if (isGoodType) {
0110     return static_cast<DataWrapper<T>*>(dataObjectp)->getData();
0111   }
0112 
0113   // When a functional has pushed a std::unique_ptr<podio::CollectionBase> into the store
0114   // We wrap it inside constexpr because if the handle has a type that is not a collection
0115   // then the static_cast will fail at compile time
0116   if constexpr (std::is_base_of_v<podio::CollectionBase, T>) {
0117     auto ptr = static_cast<AnyDataWrapper<std::unique_ptr<podio::CollectionBase>>*>(dataObjectp);
0118     return static_cast<const T*>(ptr->getData().get());
0119   }
0120   std::string errorMsg("The type provided for " + DataObjectHandle<DataWrapper<T>>::pythonRepr() +
0121                        " is different from the one of the object in the store " + typeid(*dataObjectp).name());
0122   throw std::runtime_error(errorMsg);
0123 }
0124 
0125 //---------------------------------------------------------------------------
0126 template <typename T>
0127 void DataHandle<T>::put(T* objectp) {
0128   std::unique_ptr<DataWrapper<T>> dw = std::make_unique<DataWrapper<T>>();
0129   // in case T is of primitive type, we must not change the pointer address
0130   // (see comments in ctor) instead copy the value of T into allocated memory
0131   if constexpr (std::is_integral_v<T> || std::is_floating_point_v<T>) {
0132     *m_dataPtr = *objectp;
0133   } else {
0134     m_dataPtr = objectp;
0135   }
0136   dw->setData(objectp);
0137   DataObjectHandle<DataWrapper<T>>::put(std::move(dw));
0138 }
0139 
0140 //---------------------------------------------------------------------------
0141 template <typename T>
0142 T* DataHandle<T>::put(std::unique_ptr<T> objectp) {
0143   put(objectp.get());
0144   return objectp.release();
0145 }
0146 
0147 //---------------------------------------------------------------------------
0148 /**
0149  * Create the collection, put it in the DataObjectHandle and return the
0150  * pointer to the data. Call this function if you create a collection and
0151  * want to save it.
0152  */
0153 template <typename T>
0154 T* DataHandle<T>::createAndPut() {
0155   T* objectp = new T();
0156   this->put(objectp);
0157   return objectp;
0158 }
0159 } // namespace k4FWCore
0160 
0161 template <typename T>
0162 using DataHandle [[deprecated("Use k4FWCore::DataHandle instead")]] = k4FWCore::DataHandle<T>;
0163 
0164 // temporary to allow property declaration
0165 namespace Gaudi {
0166 template <class T>
0167 class Property<k4FWCore::DataHandle<T>&> : public ::DataHandleProperty {
0168 public:
0169   Property(const std::string& name, k4FWCore::DataHandle<T>& value) : ::DataHandleProperty(name, value) {}
0170 };
0171 } // namespace Gaudi
0172 
0173 #endif