Skip to content

Commit

Permalink
Added simple DD4hep geo service, and added service bindings to Juggler
Browse files Browse the repository at this point in the history
  • Loading branch information
sly2j committed Sep 21, 2022
1 parent ffe353c commit 5d85f7d
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 32 deletions.
58 changes: 39 additions & 19 deletions JugAlgo/src/components/AlgoServiceSvc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <GaudiKernel/Service.h>
#include <JugAlgo/IAlgoServiceSvc.h>
#include <JugBase/IGeoSvc.h>

#include <algorithms/geo.h>
#include <algorithms/logger.h>
#include <algorithms/service.h>

Expand All @@ -16,6 +19,9 @@ class AlgoServiceSvc : public extends<Service, IAlgoServiceSvc> {

virtual StatusCode initialize() final;
virtual StatusCode finalize() final { return StatusCode::SUCCESS; }

private:
SmartIF<IGeoSvc> m_geoSvc;
};

DECLARE_COMPONENT(AlgoServiceSvc)
Expand All @@ -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<algorithms::LogSvc*>(svc);
const algorithms::LogLevel level{static_cast<algorithms::LogLevel>(msgLevel() > 0 ? msgLevel() - 1 : 0)};
info() << "Setting up algorithms::LogSvc with default level " << algorithms::logLevelName(level) << endmsg;
const algorithms::LogLevel level{
static_cast<algorithms::LogLevel>(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<algorithms::GeoSvc*>(svc);
geo->init(m_geoSvc->detector());
}
}

Expand Down
File renamed without changes.
3 changes: 2 additions & 1 deletion external/algorithms/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 6 additions & 4 deletions external/algorithms/core/include/algorithms/algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,22 @@ template <class... T> struct Output : std::tuple<output_type_t<T>...> {
constexpr static const size_t kSize = sizeof...(T);
};

template <class Data> using DataNames = std::array<const std::string, Data::kSize>;
template <class Data> using data_name = std::array<const std::string, Data::kSize>;

// TODO: C++20 Concepts version for better error handling
template <class InputType, class OutputType>
class Algorithm : public PropertyMixin, public LoggerMixin {
public:
using InputNames = DataNames<InputType>;
using OutputNames = DataNames<OutputType>;
using Input = InputType;
using Output = OutputType;
using InputNames = data_name<Input>;
using OutputNames = data_name<Output>;

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; }
Expand Down
39 changes: 39 additions & 0 deletions external/algorithms/core/include/algorithms/geo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#pragma once

#include <gsl/gsl>
#include <memory>

#include "DDRec/CellIDPositionConverter.h"
#include <DD4hep/Detector.h>

#include <algorithms/logger.h>
#include <algorithms/service.h>

namespace algorithms {

class GeoSvc : public LoggedService<GeoSvc> {
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<const dd4hep::Detector*> detector() const { return m_detector; }
dd4hep::DetElement world() const { return detector()->world(); }
gsl::not_null<const dd4hep::rec::CellIDPositionConverter*> cellIDPositionConverter() const {
return m_converter.get();
}

private:
dd4hep::Detector* m_detector = nullptr;
std::unique_ptr<const dd4hep::rec::CellIDPositionConverter> m_converter;

// Configuration variables. These only need to be specified if we are actually running
// in "standalone" mode (hence they're optional)
Property<std::vector<std::string>> m_xml_list{this, "detectors", {}};

ALGORITHMS_DEFINE_LOGGED_SERVICE(GeoSvc)
};

} // namespace algorithms
16 changes: 16 additions & 0 deletions external/algorithms/core/include/algorithms/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,22 @@ class LoggerMixin {
const LogSvc& m_logger;
};

// A Service base class with logger functionality
template <class SvcType> class LoggedService : public Service<SvcType>, public LoggerMixin {
protected:
LoggedService(std::string_view name) : Service<SvcType>(name), LoggerMixin(name) {}
};

} // namespace algorithms

#define ALGORITHMS_DEFINE_LOGGED_SERVICE(className) \
protected: \
className() : LoggedService<className>(#className) {} \
\
public: \
friend class Service<className>; \
className(const className&) = delete; \
void operator=(const className&) = delete; \
constexpr static const char* kName = #className;

//#define endmsg std::flush
17 changes: 9 additions & 8 deletions external/algorithms/core/include/algorithms/service.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>(#className) {} \
\
public: \
friend class Service<className>; \
className(const className&) = delete; \
void operator=(const className&) = delete;
#define ALGORITHMS_DEFINE_SERVICE(className) \
protected: \
className() : Service<className>(#className) {} \
\
public: \
friend class Service<className>; \
className(const className&) = delete; \
void operator=(const className&) = delete; \
constexpr static const char* kName = #className;

namespace algorithms {

Expand Down
27 changes: 27 additions & 0 deletions external/algorithms/core/src/geo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <algorithms/geo.h>

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<const dd4hep::rec::CellIDPositionConverter>(*m_detector);
}
} // namespace algorithms

0 comments on commit 5d85f7d

Please sign in to comment.