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