diff --git a/JugAlgo/src/components/AlgoServiceSvc.cpp b/JugAlgo/src/components/AlgoServiceSvc.cpp index c55cb07..7802126 100644 --- a/JugAlgo/src/components/AlgoServiceSvc.cpp +++ b/JugAlgo/src/components/AlgoServiceSvc.cpp @@ -5,6 +5,9 @@ #include #include +#include + +#include #include #include @@ -16,6 +19,9 @@ class AlgoServiceSvc : public extends { virtual StatusCode initialize() final; virtual StatusCode finalize() final { return StatusCode::SUCCESS; } + +private: + SmartIF m_geoSvc; }; DECLARE_COMPONENT(AlgoServiceSvc) @@ -35,30 +41,44 @@ StatusCode AlgoServiceSvc::initialize() { // Note: this code is kind of dangerous, as getting the types wrong will lead to // undefined runtime behavior. for (auto [name, svc] : serviceSvc.services()) { - if (name == "LogSvc") { + if (name == algorithms::LogSvc::kName) { auto* logger = static_cast(svc); - const algorithms::LogLevel level{static_cast(msgLevel() > 0 ? msgLevel() - 1 : 0)}; - info() << "Setting up algorithms::LogSvc with default level " << algorithms::logLevelName(level) << endmsg; + const algorithms::LogLevel level{ + static_cast(msgLevel() > 0 ? msgLevel() - 1 : 0)}; + info() << "Setting up algorithms::LogSvc with default level " + << algorithms::logLevelName(level) << endmsg; logger->defaultLevel(level); - logger->action([this](const algorithms::LogLevel l, std::string_view caller, std::string_view msg) { - const std::string text = fmt::format("[{}] {}", caller, msg); - if (l == algorithms::LogLevel::kCritical) { - this->fatal() << text << endmsg; - } else if (l == algorithms::LogLevel::kError) { - this->error() << text << endmsg; - } else if (l == algorithms::LogLevel::kWarning) { - this->warning() << text << endmsg; - } else if (l == algorithms::LogLevel::kInfo) { - this->info() << text << endmsg; - } else if (l == algorithms::LogLevel::kDebug) { - this->debug() << text << endmsg; - } else if (l == algorithms::LogLevel::kTrace) { - this->verbose() << text << endmsg; - } - }); + logger->action( + [this](const algorithms::LogLevel l, std::string_view caller, std::string_view msg) { + const std::string text = fmt::format("[{}] {}", caller, msg); + if (l == algorithms::LogLevel::kCritical) { + this->fatal() << text << endmsg; + } else if (l == algorithms::LogLevel::kError) { + this->error() << text << endmsg; + } else if (l == algorithms::LogLevel::kWarning) { + this->warning() << text << endmsg; + } else if (l == algorithms::LogLevel::kInfo) { + this->info() << text << endmsg; + } else if (l == algorithms::LogLevel::kDebug) { + this->debug() << text << endmsg; + } else if (l == algorithms::LogLevel::kTrace) { + this->verbose() << text << endmsg; + } + }); // set own log level to verbose so we actually display everything that is requested // (this overrides what was initally set through the OutputLevel property) updateMsgStreamOutputLevel(MSG::VERBOSE); + } else if (name == algorithms::GeoSvc::kName) { + // Setup geometry service + m_geoSvc = service("GeoSvc"); + if (!m_geoSvc) { + error() << "Unable to locate Geometry Service. " + << "Make sure you have GeoSvc in the right order in the configuration." << endmsg; + return StatusCode::FAILURE; + } + info() << "Setting up algorithms::GeoSvc" << endmsg; + auto* geo = static_cast(svc); + geo->init(m_geoSvc->detector()); } } diff --git a/JugReco/src/components/ClusterRecoCoG.cpp b/external/algorithms/calorimetry/src/ClusterRecoCoG.cpp similarity index 100% rename from JugReco/src/components/ClusterRecoCoG.cpp rename to external/algorithms/calorimetry/src/ClusterRecoCoG.cpp diff --git a/external/algorithms/core/CMakeLists.txt b/external/algorithms/core/CMakeLists.txt index bbbff34..153f9a2 100644 --- a/external/algorithms/core/CMakeLists.txt +++ b/external/algorithms/core/CMakeLists.txt @@ -31,7 +31,8 @@ install(TARGETS ${LIBRARY} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT bin LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT shlib ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib - INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + NAMESPACE algorithms::) install(DIRECTORY ${PROJECT_SOURCE_DIR}/${SUBDIR}/include/algorithms DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT dev) diff --git a/external/algorithms/core/include/algorithms/algorithm.h b/external/algorithms/core/include/algorithms/algorithm.h index 73a218d..5e80d51 100644 --- a/external/algorithms/core/include/algorithms/algorithm.h +++ b/external/algorithms/core/include/algorithms/algorithm.h @@ -25,20 +25,22 @@ template struct Output : std::tuple...> { constexpr static const size_t kSize = sizeof...(T); }; -template using DataNames = std::array; +template using data_name = std::array; // TODO: C++20 Concepts version for better error handling template class Algorithm : public PropertyMixin, public LoggerMixin { public: - using InputNames = DataNames; - using OutputNames = DataNames; + using Input = InputType; + using Output = OutputType; + using InputNames = data_name; + using OutputNames = data_name; Algorithm(std::string_view name, const InputNames& input_names, const OutputNames& output_names) : LoggerMixin(name), m_input_names{input_names}, m_output_names{output_names} {} void init(); - void process(const InputType& input, const OutputType& output); + void process(const Input& input, const Output& output); const InputNames& inputNames() const { return m_input_names; } const OutputNames& outputNames() const { return m_output_names; } diff --git a/external/algorithms/core/include/algorithms/geo.h b/external/algorithms/core/include/algorithms/geo.h new file mode 100644 index 0000000..319ad53 --- /dev/null +++ b/external/algorithms/core/include/algorithms/geo.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include + +#include "DDRec/CellIDPositionConverter.h" +#include + +#include +#include + +namespace algorithms { + +class GeoSvc : public LoggedService { +public: + // Initialize the geometry service, to be called after with a global detector + // pointer (will not re-initialize), or after at least the detectors property was specified + // (will load XML and then fully initialize) + void init(dd4hep::Detector* = nullptr); + + // TODO check const-ness + gsl::not_null detector() const { return m_detector; } + dd4hep::DetElement world() const { return detector()->world(); } + gsl::not_null cellIDPositionConverter() const { + return m_converter.get(); + } + +private: + dd4hep::Detector* m_detector = nullptr; + std::unique_ptr m_converter; + + // Configuration variables. These only need to be specified if we are actually running + // in "standalone" mode (hence they're optional) + Property> m_xml_list{this, "detectors", {}}; + + ALGORITHMS_DEFINE_LOGGED_SERVICE(GeoSvc) +}; + +} // namespace algorithms diff --git a/external/algorithms/core/include/algorithms/logger.h b/external/algorithms/core/include/algorithms/logger.h index 9cca2c4..a46df4f 100644 --- a/external/algorithms/core/include/algorithms/logger.h +++ b/external/algorithms/core/include/algorithms/logger.h @@ -213,6 +213,22 @@ class LoggerMixin { const LogSvc& m_logger; }; +// A Service base class with logger functionality +template class LoggedService : public Service, public LoggerMixin { +protected: + LoggedService(std::string_view name) : Service(name), LoggerMixin(name) {} +}; + } // namespace algorithms +#define ALGORITHMS_DEFINE_LOGGED_SERVICE(className) \ +protected: \ + className() : LoggedService(#className) {} \ + \ +public: \ + friend class Service; \ + className(const className&) = delete; \ + void operator=(const className&) = delete; \ + constexpr static const char* kName = #className; + //#define endmsg std::flush diff --git a/external/algorithms/core/include/algorithms/service.h b/external/algorithms/core/include/algorithms/service.h index 9c3d7c4..9c35b28 100644 --- a/external/algorithms/core/include/algorithms/service.h +++ b/external/algorithms/core/include/algorithms/service.h @@ -9,14 +9,15 @@ // - singleton --> no public constructor, no copy constructor, no assigmnent operator // - constructor should be protected so we can actually inherit from this class if needed // (mostly needed for the service base class) -#define ALGORITHMS_DEFINE_SERVICE(className) \ -protected: \ - className() : Service(#className) {} \ - \ -public: \ - friend class Service; \ - className(const className&) = delete; \ - void operator=(const className&) = delete; +#define ALGORITHMS_DEFINE_SERVICE(className) \ +protected: \ + className() : Service(#className) {} \ + \ +public: \ + friend class Service; \ + className(const className&) = delete; \ + void operator=(const className&) = delete; \ + constexpr static const char* kName = #className; namespace algorithms { diff --git a/external/algorithms/core/src/geo.cpp b/external/algorithms/core/src/geo.cpp new file mode 100644 index 0000000..ca5e2b6 --- /dev/null +++ b/external/algorithms/core/src/geo.cpp @@ -0,0 +1,27 @@ +#include + +namespace algorithms { + +void GeoSvc::init(dd4hep::Detector* det) { + if (det) { + info() << "Initializing geometry service from pre-initialized detector" << endmsg; + m_detector = det; + // no detector given, need to self-initialize + } else { + info() << "No external detector provided, self-initializing" << endmsg; + m_detector = &(dd4hep::Detector::getInstance()); + if (m_xml_list.empty()) { + // TODO handle error + } + for (std::string_view name : m_xml_list) { + info() << fmt::format("Loading compact file: {}", "name") << endmsg; + m_detector->fromCompact(std::string(name)); + } + m_detector->volumeManager(); + m_detector->apply("DD4hepVolumeManager", 0, nullptr); + } + // always: instantiate cellIDConverter + m_converter = std::make_unique(*m_detector); +} +} // namespace algorithms +