38 if (macroFile.empty()) {
42 if (!std::filesystem::exists(expandedHookFileName)) {
43 LOG(error) <<
"External geometry macro " << expandedHookFileName <<
" does not exist";
54 std::ifstream macroStream(expandedHookFileName, std::ios::in);
55 if (!macroStream.is_open()) {
56 LOG(error) <<
"Cannot open external geometry macro " << expandedHookFileName;
62 while (std::getline(macroStream, line)) {
63 auto firstNonSpace = line.find_first_not_of(
" \t");
64 if (firstNonSpace != std::string::npos && line[firstNonSpace] ==
'#') {
65 preamble += line +
"\n";
72 static std::atomic<int> instanceCounter{0};
73 std::string ns = std::string(
"o2_cadgeom_") + instanceTag +
"_" +
std::to_string(instanceCounter++);
75 if (!std::isalnum(
static_cast<unsigned char>(
c)) &&
c !=
'_') {
80 const std::string wrapped = preamble +
"\nnamespace " + ns +
" {\n" + body +
"\n}\n";
81 if (!gInterpreter->Declare(wrapped.c_str())) {
82 LOG(error) <<
"Failed to JIT external geometry macro " << expandedHookFileName;
87 const std::string globalName =
"__" + ns +
"_hook__";
88 gROOT->ProcessLine(Form(
"std::function<TGeoVolume*()> %s = %s::get_builder_hook_unchecked();",
89 globalName.c_str(), ns.c_str()));
90 auto global = gROOT->GetGlobal(globalName.c_str());
92 LOG(error) <<
"Could not retrieve geometry builder hook from macro " << expandedHookFileName;
95 auto hook = *
reinterpret_cast<std::function<TGeoVolume*()
>*>(global->GetAddress());
96 LOG(info) <<
"CAD geometry hook initialized from file " << expandedHookFileName <<
" (namespace " << ns <<
")";
100 LOG(error) <<
"CAD geometry macro " << expandedHookFileName <<
" did not return a top volume";
107 std::unordered_map<TGeoMedium*, TGeoMedium*> medium_ptr_mapping;
108 std::unordered_set<TGeoVolume*> volumes_already_treated;
112 auto transform_media = [&](TGeoVolume* vol_) {
113 if (volumes_already_treated.find(vol_) != volumes_already_treated.end()) {
117 volumes_already_treated.insert(vol_);
119 if (
dynamic_cast<TGeoVolumeAssembly*
>(vol_)) {
124 auto medium = vol_->GetMedium();
129 auto iter = medium_ptr_mapping.find(medium);
130 if (iter != medium_ptr_mapping.end()) {
133 vol_->SetMedium(iter->second);
136 LOG(info) <<
"Transforming media with name " << medium->GetName() <<
" for volume " << vol_->GetName();
139 auto curr_mat = medium->GetMaterial();
142 matmgr.Material(modulename,
counter, curr_mat->GetName(), curr_mat->GetA(), curr_mat->GetZ(), curr_mat->GetDensity(), curr_mat->GetRadLen(), curr_mat->GetIntLen());
152 const auto isvol = medium->GetParam(0);
153 const auto isxfld = medium->GetParam(1);
154 const auto sxmgmx = medium->GetParam(2);
155 const auto tmaxfd = medium->GetParam(3);
156 const auto stemax = medium->GetParam(4);
157 const auto deemax = medium->GetParam(5);
158 const auto epsil = medium->GetParam(6);
159 const auto stmin = medium->GetParam(7);
161 matmgr.Medium(modulename,
counter, medium->GetName(),
counter, isvol, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
164 auto new_med = matmgr.getTGeoMedium(modulename,
counter);
167 medium_ptr_mapping[medium] = new_med;
168 vol_->SetMedium(new_med);
174 std::function<
void(TGeoVolume*)> visit_volume;
175 visit_volume = [&](TGeoVolume* vol) ->
void {
181 transform_media(vol);
184 const int nd = vol->GetNdaughters();
185 for (
int i = 0;
i < nd; ++
i) {
186 TGeoNode*
node = vol->GetNode(
i);
190 TGeoVolume* child =
node->GetVolume();