File indexing completed on 2025-01-18 09:11:56
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Io/Root/RootMaterialDecorator.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Material/InterpolatedMaterialMap.hpp"
0013 #include "Acts/Material/Material.hpp"
0014 #include "Acts/Material/MaterialGridHelper.hpp"
0015 #include "Acts/Material/MaterialSlab.hpp"
0016 #include "Acts/Utilities/Grid.hpp"
0017 #include "Acts/Utilities/Logger.hpp"
0018 #include <Acts/Geometry/GeometryIdentifier.hpp>
0019 #include <Acts/Material/BinnedSurfaceMaterial.hpp>
0020 #include <Acts/Material/HomogeneousSurfaceMaterial.hpp>
0021 #include <Acts/Material/HomogeneousVolumeMaterial.hpp>
0022 #include <Acts/Utilities/AxisDefinitions.hpp>
0023 #include <Acts/Utilities/BinUtility.hpp>
0024 #include <Acts/Utilities/BinningType.hpp>
0025
0026 #include <algorithm>
0027 #include <cstdio>
0028 #include <functional>
0029 #include <iostream>
0030 #include <stdexcept>
0031 #include <string>
0032 #include <tuple>
0033 #include <vector>
0034
0035 #include <TFile.h>
0036 #include <TH1.h>
0037 #include <TH2.h>
0038 #include <TIterator.h>
0039 #include <TKey.h>
0040 #include <TList.h>
0041 #include <TObject.h>
0042 #include <boost/algorithm/string.hpp>
0043 #include <boost/algorithm/string/finder.hpp>
0044 #include <boost/algorithm/string/iter_find.hpp>
0045
0046 namespace Acts {
0047 class ISurfaceMaterial;
0048 class IVolumeMaterial;
0049 }
0050
0051 ActsExamples::RootMaterialDecorator::RootMaterialDecorator(
0052 const ActsExamples::RootMaterialDecorator::Config& config,
0053 Acts::Logging::Level level)
0054 : m_cfg(config),
0055 m_logger{Acts::getDefaultLogger("RootMaterialDecorator", level)} {
0056
0057 if (m_cfg.folderSurfaceNameBase.empty()) {
0058 throw std::invalid_argument("Missing surface folder name base");
0059 } else if (m_cfg.folderVolumeNameBase.empty()) {
0060 throw std::invalid_argument("Missing volume folder name base");
0061 } else if (m_cfg.fileName.empty()) {
0062 throw std::invalid_argument("Missing file name");
0063 }
0064
0065
0066 m_inputFile = TFile::Open(m_cfg.fileName.c_str());
0067 if (m_inputFile == nullptr) {
0068 throw std::ios_base::failure("Could not open '" + m_cfg.fileName + "'");
0069 }
0070
0071
0072 TList* tlist = m_inputFile->GetListOfKeys();
0073 auto tIter = tlist->MakeIterator();
0074 tIter->Reset();
0075
0076
0077 while (TKey* key = static_cast<TKey*>(tIter->Next())) {
0078
0079 std::string tdName(key->GetName());
0080
0081 ACTS_VERBOSE("Processing directory: " << tdName);
0082
0083
0084 std::vector<std::string> splitNames;
0085 iter_split(splitNames, tdName,
0086 boost::algorithm::first_finder(m_cfg.voltag));
0087
0088 if (splitNames[0] == m_cfg.folderSurfaceNameBase) {
0089
0090 std::shared_ptr<const Acts::ISurfaceMaterial> sMaterial = nullptr;
0091
0092 boost::split(splitNames, splitNames[1], boost::is_any_of("_"));
0093 Acts::GeometryIdentifier::Value volID = std::stoi(splitNames[0]);
0094
0095 iter_split(splitNames, tdName,
0096 boost::algorithm::first_finder(m_cfg.boutag));
0097 boost::split(splitNames, splitNames[1], boost::is_any_of("_"));
0098 Acts::GeometryIdentifier::Value bouID = std::stoi(splitNames[0]);
0099
0100 iter_split(splitNames, tdName,
0101 boost::algorithm::first_finder(m_cfg.laytag));
0102 boost::split(splitNames, splitNames[1], boost::is_any_of("_"));
0103 Acts::GeometryIdentifier::Value layID = std::stoi(splitNames[0]);
0104
0105 iter_split(splitNames, tdName,
0106 boost::algorithm::first_finder(m_cfg.apptag));
0107 boost::split(splitNames, splitNames[1], boost::is_any_of("_"));
0108 Acts::GeometryIdentifier::Value appID = std::stoi(splitNames[0]);
0109
0110 iter_split(splitNames, tdName,
0111 boost::algorithm::first_finder(m_cfg.sentag));
0112 Acts::GeometryIdentifier::Value senID = std::stoi(splitNames[1]);
0113
0114
0115 Acts::GeometryIdentifier geoID;
0116 geoID.setVolume(volID);
0117 geoID.setBoundary(bouID);
0118 geoID.setLayer(layID);
0119 geoID.setApproach(appID);
0120 geoID.setSensitive(senID);
0121 ACTS_VERBOSE("GeometryIdentifier re-constructed as " << geoID);
0122
0123
0124 std::string nName = tdName + "/" + m_cfg.ntag;
0125 std::string vName = tdName + "/" + m_cfg.vtag;
0126 std::string oName = tdName + "/" + m_cfg.otag;
0127 std::string minName = tdName + "/" + m_cfg.mintag;
0128 std::string maxName = tdName + "/" + m_cfg.maxtag;
0129 std::string tName = tdName + "/" + m_cfg.ttag;
0130 std::string x0Name = tdName + "/" + m_cfg.x0tag;
0131 std::string l0Name = tdName + "/" + m_cfg.l0tag;
0132 std::string aName = tdName + "/" + m_cfg.atag;
0133 std::string zName = tdName + "/" + m_cfg.ztag;
0134 std::string rhoName = tdName + "/" + m_cfg.rhotag;
0135
0136
0137 TH1F* n = dynamic_cast<TH1F*>(m_inputFile->Get(nName.c_str()));
0138 TH1F* v = dynamic_cast<TH1F*>(m_inputFile->Get(vName.c_str()));
0139 TH1F* o = dynamic_cast<TH1F*>(m_inputFile->Get(oName.c_str()));
0140 TH1F* min = dynamic_cast<TH1F*>(m_inputFile->Get(minName.c_str()));
0141 TH1F* max = dynamic_cast<TH1F*>(m_inputFile->Get(maxName.c_str()));
0142 TH2F* t = dynamic_cast<TH2F*>(m_inputFile->Get(tName.c_str()));
0143 TH2F* x0 = dynamic_cast<TH2F*>(m_inputFile->Get(x0Name.c_str()));
0144 TH2F* l0 = dynamic_cast<TH2F*>(m_inputFile->Get(l0Name.c_str()));
0145 TH2F* A = dynamic_cast<TH2F*>(m_inputFile->Get(aName.c_str()));
0146 TH2F* Z = dynamic_cast<TH2F*>(m_inputFile->Get(zName.c_str()));
0147 TH2F* rho = dynamic_cast<TH2F*>(m_inputFile->Get(rhoName.c_str()));
0148
0149 std::vector<const TH1*> hists{n, v, o, min, max, t, x0, l0, A, Z, rho};
0150
0151
0152 if (std::ranges::all_of(
0153 hists, [](const auto* hist) { return hist != nullptr; })) {
0154
0155 int nbins0 = t->GetNbinsX();
0156 int nbins1 = t->GetNbinsY();
0157
0158
0159 Acts::MaterialSlabMatrix materialMatrix(
0160 nbins1, Acts::MaterialSlabVector(nbins0, Acts::MaterialSlab()));
0161
0162
0163 if (nbins0 * nbins1 > 1) {
0164
0165 for (int ib0 = 1; ib0 <= nbins0; ++ib0) {
0166 for (int ib1 = 1; ib1 <= nbins1; ++ib1) {
0167 double dt = t->GetBinContent(ib0, ib1);
0168 if (dt > 0.) {
0169 double dx0 = x0->GetBinContent(ib0, ib1);
0170 double dl0 = l0->GetBinContent(ib0, ib1);
0171 double da = A->GetBinContent(ib0, ib1);
0172 double dz = Z->GetBinContent(ib0, ib1);
0173 double drho = rho->GetBinContent(ib0, ib1);
0174
0175 const auto material =
0176 Acts::Material::fromMassDensity(dx0, dl0, da, dz, drho);
0177 materialMatrix[ib1 - 1][ib0 - 1] =
0178 Acts::MaterialSlab(material, dt);
0179 }
0180 }
0181 }
0182
0183
0184 Acts::BinUtility bUtility;
0185 for (int ib = 1; ib < n->GetNbinsX() + 1; ++ib) {
0186 std::size_t nbins = static_cast<std::size_t>(n->GetBinContent(ib));
0187 auto val = static_cast<Acts::AxisDirection>(v->GetBinContent(ib));
0188 auto opt = static_cast<Acts::BinningOption>(o->GetBinContent(ib));
0189 float rmin = min->GetBinContent(ib);
0190 float rmax = max->GetBinContent(ib);
0191 bUtility += Acts::BinUtility(nbins, rmin, rmax, opt, val);
0192 }
0193 ACTS_VERBOSE("Created " << bUtility);
0194
0195
0196 sMaterial = std::make_shared<const Acts::BinnedSurfaceMaterial>(
0197 bUtility, std::move(materialMatrix));
0198
0199 } else {
0200
0201 double dt = t->GetBinContent(1, 1);
0202 double dx0 = x0->GetBinContent(1, 1);
0203 double dl0 = l0->GetBinContent(1, 1);
0204 double da = A->GetBinContent(1, 1);
0205 double dz = Z->GetBinContent(1, 1);
0206 double drho = rho->GetBinContent(1, 1);
0207
0208 const auto material =
0209 Acts::Material::fromMassDensity(dx0, dl0, da, dz, drho);
0210 sMaterial = std::make_shared<const Acts::HomogeneousSurfaceMaterial>(
0211 Acts::MaterialSlab(material, dt));
0212 }
0213 }
0214 ACTS_VERBOSE("Successfully read Material for : " << geoID);
0215
0216
0217 m_surfaceMaterialMap.insert({geoID, std::move(sMaterial)});
0218
0219 } else if (splitNames[0] == m_cfg.folderVolumeNameBase) {
0220
0221 std::shared_ptr<const Acts::IVolumeMaterial> vMaterial = nullptr;
0222
0223 boost::split(splitNames, splitNames[1], boost::is_any_of("_"));
0224 Acts::GeometryIdentifier::Value volID = std::stoi(splitNames[0]);
0225
0226
0227 Acts::GeometryIdentifier geoID;
0228 geoID.setVolume(volID);
0229 ACTS_VERBOSE("GeometryIdentifier re-constructed as " << geoID);
0230
0231
0232 std::string nName = tdName + "/" + m_cfg.ntag;
0233 std::string vName = tdName + "/" + m_cfg.vtag;
0234 std::string oName = tdName + "/" + m_cfg.otag;
0235 std::string minName = tdName + "/" + m_cfg.mintag;
0236 std::string maxName = tdName + "/" + m_cfg.maxtag;
0237 std::string x0Name = tdName + "/" + m_cfg.x0tag;
0238 std::string l0Name = tdName + "/" + m_cfg.l0tag;
0239 std::string aName = tdName + "/" + m_cfg.atag;
0240 std::string zName = tdName + "/" + m_cfg.ztag;
0241 std::string rhoName = tdName + "/" + m_cfg.rhotag;
0242
0243
0244 TH1F* n = dynamic_cast<TH1F*>(m_inputFile->Get(nName.c_str()));
0245 TH1F* v = dynamic_cast<TH1F*>(m_inputFile->Get(vName.c_str()));
0246 TH1F* o = dynamic_cast<TH1F*>(m_inputFile->Get(oName.c_str()));
0247 TH1F* min = dynamic_cast<TH1F*>(m_inputFile->Get(minName.c_str()));
0248 TH1F* max = dynamic_cast<TH1F*>(m_inputFile->Get(maxName.c_str()));
0249 TH1F* x0 = dynamic_cast<TH1F*>(m_inputFile->Get(x0Name.c_str()));
0250 TH1F* l0 = dynamic_cast<TH1F*>(m_inputFile->Get(l0Name.c_str()));
0251 TH1F* A = dynamic_cast<TH1F*>(m_inputFile->Get(aName.c_str()));
0252 TH1F* Z = dynamic_cast<TH1F*>(m_inputFile->Get(zName.c_str()));
0253 TH1F* rho = dynamic_cast<TH1F*>(m_inputFile->Get(rhoName.c_str()));
0254
0255
0256 if ((x0 != nullptr) && (l0 != nullptr) && (A != nullptr) &&
0257 (Z != nullptr) && (rho != nullptr)) {
0258
0259 int points = x0->GetNbinsX();
0260
0261
0262 if ((n != nullptr) && (v != nullptr) && (o != nullptr) &&
0263 (min != nullptr) && (max != nullptr)) {
0264
0265 int dim = n->GetNbinsX();
0266
0267 Acts::BinUtility bUtility;
0268 for (int ib = 1; ib < dim + 1; ++ib) {
0269 std::size_t nbins = static_cast<std::size_t>(n->GetBinContent(ib));
0270 Acts::AxisDirection val =
0271 static_cast<Acts::AxisDirection>(v->GetBinContent(ib));
0272 Acts::BinningOption opt =
0273 static_cast<Acts::BinningOption>(o->GetBinContent(ib));
0274 float rmin = min->GetBinContent(ib);
0275 float rmax = max->GetBinContent(ib);
0276 bUtility += Acts::BinUtility(nbins, rmin, rmax, opt, val);
0277 }
0278 ACTS_VERBOSE("Created " << bUtility);
0279
0280 if (dim == 2) {
0281
0282 std::function<Acts::Vector2(Acts::Vector3)> transfoGlobalToLocal;
0283 Acts::Grid2D grid = createGrid2D(bUtility, transfoGlobalToLocal);
0284
0285 Acts::Grid2D::point_t gMin = grid.minPosition();
0286 Acts::Grid2D::point_t gMax = grid.maxPosition();
0287 Acts::Grid2D::index_t gNBins = grid.numLocalBins();
0288
0289 Acts::EAxis axis1(gMin[0], gMax[0], gNBins[0]);
0290 Acts::EAxis axis2(gMin[1], gMax[1], gNBins[1]);
0291
0292
0293 Acts::MaterialGrid2D mGrid(std::make_tuple(axis1, axis2));
0294
0295 for (int p = 1; p <= points; p++) {
0296 double dx0 = x0->GetBinContent(p);
0297 double dl0 = l0->GetBinContent(p);
0298 double da = A->GetBinContent(p);
0299 double dz = Z->GetBinContent(p);
0300 double drho = rho->GetBinContent(p);
0301
0302 const auto material =
0303 Acts::Material::fromMassDensity(dx0, dl0, da, dz, drho);
0304 mGrid.at(p - 1) = material.parameters();
0305 }
0306 Acts::MaterialMapper<Acts::MaterialGrid2D> matMap(
0307 transfoGlobalToLocal, mGrid);
0308 vMaterial = std::make_shared<Acts::InterpolatedMaterialMap<
0309 Acts::MaterialMapper<Acts::MaterialGrid2D>>>(std::move(matMap),
0310 bUtility);
0311 } else if (dim == 3) {
0312
0313 std::function<Acts::Vector3(Acts::Vector3)> transfoGlobalToLocal;
0314 Acts::Grid3D grid = createGrid3D(bUtility, transfoGlobalToLocal);
0315
0316 Acts::Grid3D::point_t gMin = grid.minPosition();
0317 Acts::Grid3D::point_t gMax = grid.maxPosition();
0318 Acts::Grid3D::index_t gNBins = grid.numLocalBins();
0319
0320 Acts::EAxis axis1(gMin[0], gMax[0], gNBins[0]);
0321 Acts::EAxis axis2(gMin[1], gMax[1], gNBins[1]);
0322 Acts::EAxis axis3(gMin[2], gMax[2], gNBins[2]);
0323
0324
0325 Acts::MaterialGrid3D mGrid(std::make_tuple(axis1, axis2, axis3));
0326
0327 for (int p = 1; p <= points; p++) {
0328 double dx0 = x0->GetBinContent(p);
0329 double dl0 = l0->GetBinContent(p);
0330 double da = A->GetBinContent(p);
0331 double dz = Z->GetBinContent(p);
0332 double drho = rho->GetBinContent(p);
0333
0334 const auto material =
0335 Acts::Material::fromMassDensity(dx0, dl0, da, dz, drho);
0336 mGrid.at(p - 1) = material.parameters();
0337 }
0338 Acts::MaterialMapper<Acts::MaterialGrid3D> matMap(
0339 transfoGlobalToLocal, mGrid);
0340 vMaterial = std::make_shared<Acts::InterpolatedMaterialMap<
0341 Acts::MaterialMapper<Acts::MaterialGrid3D>>>(std::move(matMap),
0342 bUtility);
0343 }
0344 } else {
0345
0346 double dx0 = x0->GetBinContent(1);
0347 double dl0 = l0->GetBinContent(1);
0348 double da = A->GetBinContent(1);
0349 double dz = Z->GetBinContent(1);
0350 double drho = rho->GetBinContent(1);
0351
0352 const auto material =
0353 Acts::Material::fromMassDensity(dx0, dl0, da, dz, drho);
0354 vMaterial =
0355 std::make_shared<Acts::HomogeneousVolumeMaterial>(material);
0356 }
0357 }
0358 ACTS_VERBOSE("Successfully read Material for : " << geoID);
0359
0360
0361 m_volumeMaterialMap.insert({geoID, std::move(vMaterial)});
0362
0363
0364 } else {
0365 ACTS_ERROR(
0366 "Invalid FolderName, does not match any entry in the root file");
0367 }
0368 }
0369 }
0370
0371 ActsExamples::RootMaterialDecorator::~RootMaterialDecorator() {
0372 if (m_inputFile != nullptr) {
0373 m_inputFile->Close();
0374 }
0375 }