File indexing completed on 2025-07-05 08:15:24
0001
0002
0003
0004
0005 #include <JANA/JException.h>
0006 #include <Parsers/Printout.h>
0007 #include <TGeoManager.h>
0008 #include <fmt/color.h>
0009 #include <fmt/core.h>
0010 #include <fmt/format.h>
0011 #include <algorithm>
0012 #include <cstdlib>
0013 #include <exception>
0014 #include <filesystem>
0015 #include <iostream>
0016 #include <stdexcept>
0017 #include <utility>
0018 #include <vector>
0019
0020 #include "DD4hep_service.h"
0021 #include "services/log/Log_service.h"
0022
0023
0024
0025
0026 void DD4hep_service::acquire_services(JServiceLocator* srv_locator) {
0027
0028 auto log_service = srv_locator->get<Log_service>();
0029 m_log = log_service->logger("dd4hep");
0030
0031
0032 std::string print_level_str{"WARNING"};
0033 m_app->SetDefaultParameter("dd4hep:print_level", print_level_str,
0034 "Set DD4hep print level (see DD4hep/Printout.h)");
0035 dd4hep::setPrintLevel(dd4hep::decodePrintLevel(print_level_str));
0036
0037
0038 TGeoManager::SetVerboseLevel(dd4hep::printLevel() <= dd4hep::PrintLevel::INFO ? 1 : 0);
0039 }
0040
0041
0042
0043
0044 DD4hep_service::~DD4hep_service() {
0045 try {
0046 if (m_dd4hepGeo) {
0047 m_dd4hepGeo->destroyInstance();
0048 }
0049 m_dd4hepGeo = nullptr;
0050 } catch (...) {
0051 }
0052 }
0053
0054
0055
0056
0057
0058
0059
0060 gsl::not_null<const dd4hep::Detector*> DD4hep_service::detector() {
0061 std::call_once(init_flag, &DD4hep_service::Initialize, this);
0062 return m_dd4hepGeo.get();
0063 }
0064
0065
0066
0067
0068
0069
0070
0071 gsl::not_null<const dd4hep::rec::CellIDPositionConverter*> DD4hep_service::converter() {
0072 std::call_once(init_flag, &DD4hep_service::Initialize, this);
0073 return m_cellid_converter.get();
0074 }
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 void DD4hep_service::Initialize() {
0085
0086 if (m_dd4hepGeo) {
0087 m_log->warn("DD4hep_service already initialized!");
0088 }
0089
0090
0091
0092
0093
0094 auto* detector_config_env = std::getenv("DETECTOR_CONFIG");
0095 auto* detector_path_env = std::getenv("DETECTOR_PATH");
0096
0097 std::string detector_config;
0098
0099 if (detector_config_env != nullptr) {
0100 detector_config = detector_config_env;
0101 }
0102
0103
0104 if (!detector_config.empty()) {
0105 m_xml_files.push_back(std::string(detector_path_env != nullptr ? detector_path_env : ".") +
0106 "/" + detector_config + ".xml");
0107 }
0108
0109
0110
0111 m_app->SetDefaultParameter("dd4hep:xml_files", m_xml_files,
0112 "Comma separated list of XML files describing the DD4hep geometry. "
0113 "(Defaults to ${DETECTOR_PATH}/${DETECTOR_CONFIG}.xml using envars.)");
0114
0115 if (m_xml_files.empty()) {
0116 m_log->error("No dd4hep XML file specified for the geometry!");
0117 m_log->error("Set your DETECTOR_PATH and DETECTOR_CONFIG environment variables");
0118 m_log->error("(the latter is typically done by sourcing the thisepic.sh");
0119 m_log->error("script the epic directory.)");
0120 throw std::runtime_error("No dd4hep XML file specified.");
0121 }
0122
0123
0124
0125
0126 auto tickerEnabled = m_app->IsTickerEnabled();
0127 m_app->SetTicker(false);
0128
0129
0130 auto detector = dd4hep::Detector::make_unique("");
0131 try {
0132 m_log->info("Loading DD4hep geometry from {} files", m_xml_files.size());
0133 for (auto& filename : m_xml_files) {
0134
0135 auto resolved_filename = resolveFileName(filename, detector_path_env);
0136
0137 m_log->info(" - loading geometry file: '{}' (patience ....)", resolved_filename);
0138 try {
0139 detector->fromCompact(resolved_filename);
0140 } catch (
0141 std::runtime_error& e) {
0142 throw JException(e.what());
0143 }
0144 }
0145 detector->volumeManager();
0146 detector->apply("DD4hepVolumeManager", 0, nullptr);
0147 m_cellid_converter = std::make_unique<const dd4hep::rec::CellIDPositionConverter>(*detector);
0148 m_dd4hepGeo = std::move(detector);
0149
0150 m_log->info("Geometry successfully loaded.");
0151 } catch (std::exception& e) {
0152 m_log->error("Problem loading geometry: {}", e.what());
0153 throw std::runtime_error(fmt::format("Problem loading geometry: {}", e.what()));
0154 }
0155
0156
0157 m_app->SetTicker(tickerEnabled);
0158 }
0159
0160 std::string DD4hep_service::resolveFileName(const std::string& filename, char* detector_path_env) {
0161
0162 std::string result(filename);
0163
0164
0165 if (!std::filesystem::exists(result)) {
0166
0167
0168 if (detector_path_env != nullptr) {
0169
0170
0171 result = std::string(detector_path_env) + "/" + filename;
0172
0173 if (!std::filesystem::exists(result)) {
0174
0175
0176
0177 auto mess = fmt::format(fmt::emphasis::bold | fg(fmt::color::red), "ERROR: ");
0178 mess += fmt::format(fmt::emphasis::bold, "file: {} does not exist!", filename);
0179 mess += "\nCheck that your DETECTOR_PATH and DETECTOR_CONFIG environment variables are set "
0180 "correctly.";
0181 std::cerr << std::endl
0182 << std::endl
0183 << mess << std::endl
0184 << std::endl;
0185 std::_Exit(EXIT_FAILURE);
0186 }
0187 }
0188 }
0189 return result;
0190 }