Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-06-26 07:06:31

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2022 Sylvester Joosten
0003 
0004 #include <string>
0005 #include <type_traits>
0006 
0007 #include <algorithms/algorithm.h>
0008 #include <algorithms/type_traits.h>
0009 
0010 #include <GaudiAlg/GaudiAlgorithm.h>
0011 #include <GaudiKernel/Service.h>
0012 #include <JugAlgo/IAlgoServiceSvc.h>
0013 #include <JugAlgo/detail/DataProxy.h>
0014 
0015 #define JUGALGO_DEFINE_ALGORITHM(algorithm, impl, ns)                                              \
0016   using algorithm##Base = Jug::Algo::Algorithm<impl>;                                              \
0017   namespace ns {                                                                                   \
0018   struct algorithm : algorithm##Base {                                                             \
0019     algorithm(const std::string& name, ISvcLocator* svcLoc) : algorithm##Base(name, svcLoc) {}     \
0020   };                                                                                               \
0021   DECLARE_COMPONENT(algorithm)                                                                     \
0022   }
0023 
0024 namespace Jug::Algo {
0025 
0026 template <class AlgoImpl> class Algorithm : public GaudiAlgorithm {
0027 public:
0028   using algo_type   = AlgoImpl;
0029   using input_type  = typename algo_type::input_type;
0030   using output_type = typename algo_type::output_type;
0031   using Input       = typename algo_type::Input;
0032   using Output      = typename algo_type::Output;
0033 
0034   Algorithm(const std::string& name, ISvcLocator* svcLoc)
0035       : GaudiAlgorithm(name, svcLoc)
0036       , m_algo{name}
0037       , m_output{this, m_algo.outputNames()}
0038       , m_input{this, m_algo.inputNames()} {
0039     defineProperties();
0040   }
0041 
0042   StatusCode initialize() override {
0043     debug() << "Initializing " << name() << endmsg;
0044 
0045     // Algorithms uses exceptions, Gaudi uses StatusCode --> catch and propagate
0046     try {
0047       // Grab the AlgoServiceSvc
0048       m_algo_svc = service("AlgoServiceSvc");
0049       if (!m_algo_svc) {
0050         error() << "Unable to get an instance of the AlgoServiceSvc" << endmsg;
0051         return StatusCode::FAILURE;
0052       }
0053 
0054       // Forward the log level of this algorithm
0055       const algorithms::LogLevel level{
0056           static_cast<algorithms::LogLevel>(msgLevel() > 0 ? msgLevel() - 1 : 0)};
0057       debug() << "Setting the logger level to " << algorithms::logLevelName(level) << endmsg;
0058       m_algo.level(level);
0059 
0060       // Init our data structures
0061       debug() << "Initializing data structures" << endmsg;
0062       m_input.init();
0063       m_output.init();
0064 
0065       // configure properties
0066       debug() << "Configuring properties" << endmsg;
0067       initProperties();
0068 
0069       // validate properties
0070       debug() << "Validating properties" << endmsg;
0071       m_algo.validate();
0072 
0073       // call the internal algorithm init
0074       debug() << "Initializing underlying algorithm " << m_algo.name() << endmsg;
0075       m_algo.init();
0076     } catch (const std::exception& e) {
0077       fatal() << e.what() << endmsg;
0078       return StatusCode::FAILURE;
0079     }
0080     return StatusCode::SUCCESS;
0081   }
0082 
0083   StatusCode execute() override {
0084     try {
0085       m_algo.process(m_input.get(), m_output.get());
0086     } catch (const std::exception& e) {
0087       error() << e.what() << endmsg;
0088       return StatusCode::FAILURE;
0089     }
0090     return StatusCode::SUCCESS;
0091   }
0092 
0093 protected:
0094   template <typename T> void setAlgoProp(std::string_view name, T&& value) {
0095     m_algo.template setProperty<T>(name, value);
0096   }
0097   template <typename T> T getAlgoProp(std::string name) const {
0098     return m_algo.template getProperty<T>(name);
0099   }
0100   bool hasAlgoProp(std::string_view name) const { return m_algo.hasProperty(name); }
0101 
0102 private:
0103   // to be called during construction (before init())
0104   void defineProperties() {
0105     for (const auto& [key, prop] : m_algo.getProperties()) {
0106       std::visit(
0107           [this, key = key](auto&& val) {
0108             using T = std::decay_t<decltype(val)>;
0109             this->m_props.emplace(
0110                 key, std::make_unique<Gaudi::Property<T>>(this, std::string(key), val));
0111           },
0112           prop.get());
0113     }
0114   }
0115 
0116   // to be called during init() --> will actually set the underlying alo properties
0117   void initProperties() {
0118     for (const auto& [key, prop] : m_algo.getProperties()) {
0119       std::visit(
0120           [this, key = key](auto&& val) {
0121             using T                = std::decay_t<decltype(val)>;
0122             const auto* gaudi_prop = static_cast<Gaudi::Property<T>*>(this->m_props.at(key).get());
0123             const auto prop_val    = gaudi_prop->value();
0124             this->m_algo.setProperty(key, prop_val);
0125           },
0126           prop.get());
0127     }
0128   }
0129 
0130   algo_type m_algo;
0131   SmartIF<IAlgoServiceSvc> m_algo_svc;
0132   detail::DataProxy<output_type> m_output;
0133   detail::DataProxy<input_type> m_input;
0134   std::map<std::string_view, std::unique_ptr<Gaudi::Details::PropertyBase>> m_props;
0135 };
0136 
0137 } // namespace Jug::Algo
0138