Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-12 07:52:56

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include "Acts/Plugins/Root/RootMaterialMapIo.hpp"
0010 
0011 #include "Acts/Geometry/GeometryIdentifier.hpp"
0012 #include "Acts/Material/BinnedSurfaceMaterial.hpp"
0013 #include "Acts/Material/GridSurfaceMaterial.hpp"
0014 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0015 #include "Acts/Material/Material.hpp"
0016 #include "Acts/Material/MaterialSlab.hpp"
0017 #include "Acts/Surfaces/Surface.hpp"
0018 #include "Acts/Utilities/Enumerate.hpp"
0019 
0020 #include <TFile.h>
0021 #include <TH1I.h>
0022 #include <TH2F.h>
0023 #include <TKey.h>
0024 #include <TList.h>
0025 #include <TObject.h>
0026 #include <TTree.h>
0027 #include <boost/algorithm/string.hpp>
0028 #include <boost/algorithm/string/finder.hpp>
0029 #include <boost/algorithm/string/iter_find.hpp>
0030 
0031 void Acts::RootMaterialMapIo::write(TFile& rFile,
0032                                     const GeometryIdentifier& geoID,
0033                                     const ISurfaceMaterial& surfaceMaterial,
0034                                     const Options& options) {
0035   /// Change to the file
0036   rFile.cd();
0037 
0038   // Homogeneous surface material writing into one tree
0039   auto homogeneousMaterial =
0040       dynamic_cast<const HomogeneousSurfaceMaterial*>(&surfaceMaterial);
0041   if (homogeneousMaterial != nullptr) {
0042     if (m_hTree == nullptr) {
0043       m_hTree = new TTree(options.homogeneousMaterialTreeName.c_str(),
0044                           "Homogeneous Material Tree");
0045       connectForWrite(*m_hTree, m_homogenousMaterialTreePayload);
0046     }
0047     fillMaterialSlab(m_homogenousMaterialTreePayload,
0048                      homogeneousMaterial->materialSlab());
0049     m_homogenousMaterialTreePayload.hGeoId = geoID.value();
0050     m_hTree->Fill();
0051     return;
0052   }
0053 
0054   // Binned surface material writing
0055   auto bsMaterial =
0056       dynamic_cast<const BinnedSurfaceMaterial*>(&surfaceMaterial);
0057   if (bsMaterial != nullptr) {
0058     // decode the geometryID
0059     const auto gvolID = geoID.volume();
0060     const auto gbouID = geoID.boundary();
0061     const auto glayID = geoID.layer();
0062     const auto gappID = geoID.approach();
0063     const auto gsenID = geoID.sensitive();
0064     // create the directory
0065     std::string tdName = options.folderSurfaceNameBase.c_str();
0066     tdName += m_cfg.volumePrefix + std::to_string(gvolID);
0067     tdName += m_cfg.portalPrefix + std::to_string(gbouID);
0068     tdName += m_cfg.layerPrefix + std::to_string(glayID);
0069     tdName += m_cfg.passivePrefix + std::to_string(gappID);
0070     tdName += m_cfg.sensitivePrefix + std::to_string(gsenID);
0071     // create a new directory
0072     rFile.mkdir(tdName.c_str());
0073     rFile.cd(tdName.c_str());
0074 
0075     // Boundary condistions
0076     // Get the binning data
0077     auto& binningData = bsMaterial->binUtility().binningData();
0078     // 1-D or 2-D maps
0079     auto bins = static_cast<int>(binningData.size());
0080     auto fBins = static_cast<float>(bins);
0081 
0082     // The bin number information
0083     TH1F n(m_cfg.nBinsHistName.c_str(), "bins; bin", bins, -0.5, fBins - 0.5);
0084 
0085     // The binning value information
0086     TH1F v(m_cfg.axisDirHistName.c_str(), "binning values; bin", bins, -0.5,
0087            fBins - 0.5);
0088 
0089     // The binning option information
0090     TH1F o(m_cfg.axisBoundaryTypeHistName.c_str(), "binning options; bin", bins,
0091            -0.5, fBins - 0.5);
0092 
0093     // The binning option information - range min
0094     TH1F rmin(m_cfg.minRangeHistName.c_str(), "min; bin", bins, -0.5,
0095               fBins - 0.5);
0096 
0097     // The binning option information - range max
0098     TH1F rmax(m_cfg.maxRangeHistName.c_str(), "max; bin", bins, -0.5,
0099               fBins - 0.5);
0100 
0101     // Now fill the histogram content
0102     for (auto [b, bData] : enumerate(binningData)) {
0103       // Fill: nbins, value, option, min, max
0104       n.SetBinContent(static_cast<int>(b) + 1, static_cast<int>(bData.bins()));
0105       v.SetBinContent(static_cast<int>(b) + 1,
0106                       static_cast<int>(bData.binvalue));
0107       o.SetBinContent(static_cast<int>(b) + 1, static_cast<int>(bData.option));
0108       rmin.SetBinContent(static_cast<int>(b) + 1, bData.min);
0109       rmax.SetBinContent(static_cast<int>(b) + 1, bData.max);
0110     }
0111     n.Write();
0112     v.Write();
0113     o.Write();
0114     rmin.Write();
0115     rmax.Write();
0116 
0117     // If compressed writing is not enabled, write the binned surface material
0118     // as histograms
0119     if (!options.indexedMaterial) {
0120       fillBinnedSurfaceMaterial(*bsMaterial);
0121       return;
0122     }
0123 
0124     // Otherwise, write the binned surface material into the TTree
0125     if (m_gTree == nullptr) {
0126       // Back to file level
0127       rFile.cd();
0128       m_gTree = new TTree(options.indexedMaterialTreeName.c_str(),
0129                           "Indexed Material Tree");
0130       connectForWrite(*m_gTree, m_indexedMaterialTreePayload);
0131       // Back to the directory
0132       rFile.cd(tdName.c_str());
0133     }
0134     fillBinnedSurfaceMaterial(m_indexedMaterialTreePayload, *bsMaterial);
0135     return;
0136   }
0137 }
0138 
0139 void Acts::RootMaterialMapIo::write(
0140     TFile& rFile, const TrackingGeometryMaterial& detectorMaterial,
0141     const Options& options) {
0142   const auto& [surfaceMaterials, volumeMaterials] = detectorMaterial;
0143   for (const auto& [geoID, sMaterial] : surfaceMaterials) {
0144     write(rFile, geoID, *sMaterial, options);
0145   }
0146   if (m_hTree != nullptr) {
0147     m_hTree->Write();
0148   }
0149   if (m_gTree != nullptr) {
0150     m_gTree->Write();
0151   }
0152 }
0153 
0154 void Acts::RootMaterialMapIo::connectForWrite(
0155     TTree& rTree, MaterialTreePayload& treePayload) {
0156   if (&treePayload == &m_homogenousMaterialTreePayload) {
0157     rTree.Branch("hGeoId", &treePayload.hGeoId);
0158   }
0159   rTree.Branch(m_cfg.thicknessHistName.c_str(), &treePayload.ht);
0160   rTree.Branch(m_cfg.x0HistName.c_str(), &treePayload.hX0);
0161   rTree.Branch(m_cfg.l0HistName.c_str(), &treePayload.hL0);
0162   rTree.Branch(m_cfg.aHistName.c_str(), &treePayload.hA);
0163   rTree.Branch(m_cfg.zHistName.c_str(), &treePayload.hZ);
0164   rTree.Branch(m_cfg.rhoHistName.c_str(), &treePayload.hRho);
0165 }
0166 
0167 void Acts::RootMaterialMapIo::connectForRead(TTree& rTree,
0168                                              MaterialTreePayload& treePayload) {
0169   if (&treePayload == &m_homogenousMaterialTreePayload) {
0170     rTree.SetBranchAddress("hGeoId", &treePayload.hGeoId);
0171   }
0172   rTree.SetBranchAddress(m_cfg.thicknessHistName.c_str(), &treePayload.ht);
0173   rTree.SetBranchAddress(m_cfg.x0HistName.c_str(), &treePayload.hX0);
0174   rTree.SetBranchAddress(m_cfg.l0HistName.c_str(), &treePayload.hL0);
0175   rTree.SetBranchAddress(m_cfg.aHistName.c_str(), &treePayload.hA);
0176   rTree.SetBranchAddress(m_cfg.zHistName.c_str(), &treePayload.hZ);
0177   rTree.SetBranchAddress(m_cfg.rhoHistName.c_str(), &treePayload.hRho);
0178 }
0179 
0180 void Acts::RootMaterialMapIo::fillMaterialSlab(
0181     MaterialTreePayload& payload, const MaterialSlab& materialSlab) {
0182   payload.ht = materialSlab.thickness();
0183   payload.hX0 = materialSlab.material().X0();
0184   payload.hL0 = materialSlab.material().L0();
0185   payload.hA = materialSlab.material().Ar();
0186   payload.hZ = materialSlab.material().Z();
0187   payload.hRho = materialSlab.material().massDensity();
0188 }
0189 
0190 void Acts::RootMaterialMapIo::fillBinnedSurfaceMaterial(
0191     const BinnedSurfaceMaterial& bsMaterial) {
0192   auto bins0 = static_cast<int>(bsMaterial.binUtility().bins(0));
0193   auto bins1 = static_cast<int>(bsMaterial.binUtility().bins(1));
0194   auto fBins0 = static_cast<float>(bins0);
0195   auto fBins1 = static_cast<float>(bins1);
0196 
0197   TH2F t(m_cfg.thicknessHistName.c_str(), "thickness [mm] ;b0 ;b1", bins0, -0.5,
0198          fBins0 - 0.5, bins1, -0.5, fBins1 - 0.5);
0199   TH2F x0(m_cfg.x0HistName.c_str(), "X_{0} [mm] ;b0 ;b1", bins0, -0.5,
0200           fBins0 - 0.5, bins1, -0.5, fBins1 - 0.5);
0201   TH2F l0(m_cfg.l0HistName.c_str(), "#Lambda_{0} [mm] ;b0 ;b1", bins0, -0.5,
0202           fBins0 - 0.5, bins1, -0.5, fBins1 - 0.5);
0203   TH2F A(m_cfg.aHistName.c_str(), "X_{0} [mm] ;b0 ;b1", bins0, -0.5,
0204          fBins0 - 0.5, bins1, -0.5, fBins1 - 0.5);
0205   TH2F Z(m_cfg.zHistName.c_str(), "#Lambda_{0} [mm] ;b0 ;b1", bins0, -0.5,
0206          fBins0 - 0.5, bins1, -0.5, fBins1 - 0.5);
0207   TH2F rho(m_cfg.rhoHistName.c_str(), "#rho [g/mm^3] ;b0 ;b1", bins0, -0.5,
0208            fBins0 - 0.5, bins1, -0.5, fBins1 - 0.5);
0209 
0210   // Loop over the material matrix and fill the histograms
0211   const auto& materialMatrix = bsMaterial.fullMaterial();
0212   for (auto [b1, materialVector] : enumerate(materialMatrix)) {
0213     for (auto [b0, mat] : enumerate(materialVector)) {
0214       t.SetBinContent(static_cast<int>(b0) + 1, static_cast<int>(b1) + 1,
0215                       mat.thickness());
0216       x0.SetBinContent(static_cast<int>(b0) + 1, static_cast<int>(b1) + 1,
0217                        mat.material().X0());
0218       l0.SetBinContent(static_cast<int>(b0) + 1, static_cast<int>(b1) + 1,
0219                        mat.material().L0());
0220       A.SetBinContent(static_cast<int>(b0) + 1, static_cast<int>(b1) + 1,
0221                       mat.material().Ar());
0222       Z.SetBinContent(static_cast<int>(b0) + 1, static_cast<int>(b1) + 1,
0223                       mat.material().Z());
0224       rho.SetBinContent(static_cast<int>(b0) + 1, static_cast<int>(b1) + 1,
0225                         mat.material().massDensity());
0226     }
0227   }
0228   t.Write();
0229   x0.Write();
0230   l0.Write();
0231   A.Write();
0232   Z.Write();
0233   rho.Write();
0234 }
0235 
0236 void Acts::RootMaterialMapIo::fillBinnedSurfaceMaterial(
0237     MaterialTreePayload& payload, const BinnedSurfaceMaterial& bsMaterial) {
0238   std::size_t bins0 = bsMaterial.binUtility().bins(0);
0239   std::size_t bins1 = bsMaterial.binUtility().bins(1);
0240 
0241   TH2I idx(m_cfg.indexHistName.c_str(), "indices; bin0; bin1",
0242            static_cast<int>(bins0), -0.5, static_cast<float>(bins0) - 0.5,
0243            static_cast<int>(bins1), -0.5, static_cast<float>(bins1) - 0.5);
0244   // lLop over the material matrix, record the index and fill the indexed tree
0245   const auto& materialMatrix = bsMaterial.fullMaterial();
0246   for (auto [b1, materialVector] : enumerate(materialMatrix)) {
0247     for (auto [b0, mat] : enumerate(materialVector)) {
0248       idx.SetBinContent(static_cast<int>(b0) + 1, static_cast<int>(b1) + 1,
0249                         static_cast<float>(payload.index));
0250       payload.index++;
0251       fillMaterialSlab(payload, mat);
0252       m_gTree->Fill();
0253     }
0254   }
0255   idx.Write();
0256 }
0257 
0258 Acts::TrackingGeometryMaterial Acts::RootMaterialMapIo::read(
0259     TFile& rFile, const Options& options) {
0260   TrackingGeometryMaterial detectorMaterial;
0261 
0262   auto& [surfaceMaterials, volumeMaterials] = detectorMaterial;
0263 
0264   auto homogeneousMaterialTree = dynamic_cast<TTree*>(
0265       rFile.Get(options.homogeneousMaterialTreeName.c_str()));
0266 
0267   // Read homogeneous material tree
0268   if (homogeneousMaterialTree != nullptr) {
0269     connectForRead(*homogeneousMaterialTree, m_homogenousMaterialTreePayload);
0270     for (int i = 0; i < homogeneousMaterialTree->GetEntries(); ++i) {
0271       homogeneousMaterialTree->GetEntry(i);
0272       GeometryIdentifier geoID(m_homogenousMaterialTreePayload.hGeoId);
0273       MaterialSlab materialSlab(
0274           Material::fromMassDensity(m_homogenousMaterialTreePayload.hX0,
0275                                     m_homogenousMaterialTreePayload.hL0,
0276                                     m_homogenousMaterialTreePayload.hA,
0277                                     m_homogenousMaterialTreePayload.hZ,
0278                                     m_homogenousMaterialTreePayload.hRho),
0279           m_homogenousMaterialTreePayload.ht);
0280       auto homogeneousMaterial =
0281           std::make_shared<HomogeneousSurfaceMaterial>(materialSlab);
0282       surfaceMaterials.try_emplace(geoID, homogeneousMaterial);
0283     }
0284   }
0285 
0286   // Read the binned surface material, if there - connect it to the payload
0287   auto indexedMaterialTree =
0288       dynamic_cast<TTree*>(rFile.Get(options.indexedMaterialTreeName.c_str()));
0289   if (indexedMaterialTree != nullptr) {
0290     connectForRead(*indexedMaterialTree, m_indexedMaterialTreePayload);
0291   }
0292 
0293   // Get the list of keys from the file
0294   TList* tlist = rFile.GetListOfKeys();
0295   auto tIter = tlist->MakeIterator();
0296   tIter->Reset();
0297 
0298   // Iterate over the keys in the file
0299   while (auto key = static_cast<TKey*>(tIter->Next())) {
0300     // Remember the directory
0301     std::string tdName(key->GetName());
0302 
0303     ACTS_VERBOSE("Processing directory: " << tdName);
0304 
0305     // volume
0306     std::vector<std::string> splitNames;
0307     iter_split(splitNames, tdName,
0308                boost::algorithm::first_finder(m_cfg.volumePrefix));
0309     // Surface Material
0310     if (splitNames[0] == options.folderSurfaceNameBase) {
0311       // The surface material to be read in for this
0312       std::shared_ptr<const Acts::ISurfaceMaterial> sMaterial = nullptr;
0313 
0314       boost::split(splitNames, splitNames[1], boost::is_any_of("_"));
0315       GeometryIdentifier::Value volID = std::stoi(splitNames[0]);
0316       // boundary
0317       iter_split(splitNames, tdName,
0318                  boost::algorithm::first_finder(m_cfg.portalPrefix));
0319       boost::split(splitNames, splitNames[1], boost::is_any_of("_"));
0320       GeometryIdentifier::Value bouID = std::stoi(splitNames[0]);
0321       // layer
0322       iter_split(splitNames, tdName,
0323                  boost::algorithm::first_finder(m_cfg.layerPrefix));
0324       boost::split(splitNames, splitNames[1], boost::is_any_of("_"));
0325       GeometryIdentifier::Value layID = std::stoi(splitNames[0]);
0326       // approach
0327       iter_split(splitNames, tdName,
0328                  boost::algorithm::first_finder(m_cfg.passivePrefix));
0329       boost::split(splitNames, splitNames[1], boost::is_any_of("_"));
0330       GeometryIdentifier::Value appID = std::stoi(splitNames[0]);
0331       // sensitive
0332       iter_split(splitNames, tdName,
0333                  boost::algorithm::first_finder(m_cfg.sensitivePrefix));
0334       GeometryIdentifier::Value senID = std::stoi(splitNames[1]);
0335 
0336       // Reconstruct the geometry ID
0337       auto geoID = GeometryIdentifier()
0338                        .withVolume(volID)
0339                        .withBoundary(bouID)
0340                        .withLayer(layID)
0341                        .withApproach(appID)
0342                        .withSensitive(senID);
0343 
0344       ACTS_VERBOSE("GeometryIdentifier re-constructed as " << geoID);
0345 
0346       auto texturedSurfaceMaterial =
0347           readTextureSurfaceMaterial(rFile, tdName, indexedMaterialTree);
0348       surfaceMaterials.try_emplace(geoID, texturedSurfaceMaterial);
0349     }
0350   }
0351   return detectorMaterial;
0352 }
0353 
0354 std::shared_ptr<const Acts::ISurfaceMaterial>
0355 Acts::RootMaterialMapIo::readTextureSurfaceMaterial(
0356     TFile& rFile, const std::string& tdName, TTree* indexedMaterialTree) {
0357   std::shared_ptr<const Acts::ISurfaceMaterial> texturedSurfaceMaterial =
0358       nullptr;
0359 
0360   // Construct the common names & get the common histograms
0361   std::string nName = tdName + "/" + m_cfg.nBinsHistName;
0362   std::string vName = tdName + "/" + m_cfg.axisDirHistName;
0363   std::string oName = tdName + "/" + m_cfg.axisBoundaryTypeHistName;
0364   std::string minName = tdName + "/" + m_cfg.minRangeHistName;
0365   std::string maxName = tdName + "/" + m_cfg.maxRangeHistName;
0366   // Get the histograms
0367   auto n = dynamic_cast<TH1F*>(rFile.Get(nName.c_str()));
0368   auto v = dynamic_cast<TH1F*>(rFile.Get(vName.c_str()));
0369   auto o = dynamic_cast<TH1F*>(rFile.Get(oName.c_str()));
0370   auto minh = dynamic_cast<TH1F*>(rFile.Get(minName.c_str()));
0371   auto maxh = dynamic_cast<TH1F*>(rFile.Get(maxName.c_str()));
0372 
0373   std::vector<const TH1*> hists{n, v, o, minh, maxh};
0374   if (std::ranges::any_of(hists,
0375                           [](const auto* hist) { return hist == nullptr; })) {
0376     ACTS_ERROR(
0377         "Failed to read all required histograms for textured surface "
0378         "material from file: "
0379         << rFile.GetName());
0380     return nullptr;
0381   }
0382 
0383   // Now reconstruct the bin untilities
0384   BinUtility bUtility;
0385   for (int ib = 1; ib < n->GetNbinsX() + 1; ++ib) {
0386     auto nbins = static_cast<std::size_t>(n->GetBinContent(ib));
0387     auto val = static_cast<AxisDirection>(v->GetBinContent(ib));
0388     auto opt = static_cast<BinningOption>(o->GetBinContent(ib));
0389     auto rmin = static_cast<float>(minh->GetBinContent(ib));
0390     auto rmax = static_cast<float>(maxh->GetBinContent(ib));
0391     bUtility += Acts::BinUtility(nbins, rmin, rmax, opt, val);
0392   }
0393   ACTS_VERBOSE("Created " << bUtility);
0394 
0395   /// Draw from histogram only source
0396   if (indexedMaterialTree == nullptr) {
0397     // Construct the names for histogram type storage
0398     std::string tName = tdName + "/" + m_cfg.thicknessHistName;
0399     std::string x0Name = tdName + "/" + m_cfg.x0HistName;
0400     std::string l0Name = tdName + "/" + m_cfg.l0HistName;
0401     std::string aName = tdName + "/" + m_cfg.aHistName;
0402     std::string zName = tdName + "/" + m_cfg.zHistName;
0403     std::string rhoName = tdName + "/" + m_cfg.rhoHistName;
0404 
0405     // Get the histograms
0406     auto t = dynamic_cast<TH2F*>(rFile.Get(tName.c_str()));
0407     auto x0 = dynamic_cast<TH2F*>(rFile.Get(x0Name.c_str()));
0408     auto l0 = dynamic_cast<TH2F*>(rFile.Get(l0Name.c_str()));
0409     auto A = dynamic_cast<TH2F*>(rFile.Get(aName.c_str()));
0410     auto Z = dynamic_cast<TH2F*>(rFile.Get(zName.c_str()));
0411     auto rho = dynamic_cast<TH2F*>(rFile.Get(rhoName.c_str()));
0412 
0413     hists = {t, x0, l0, A, Z, rho};
0414 
0415     // Only go on when you have all histograms
0416     if (std::ranges::all_of(hists,
0417                             [](const auto* hist) { return hist != nullptr; })) {
0418       // Get the number of bins
0419       int nbins0 = t->GetNbinsX();
0420       int nbins1 = t->GetNbinsY();
0421       // The material matrix
0422       MaterialSlabMatrix materialMatrix(
0423           nbins1, MaterialSlabVector(nbins0, MaterialSlab::Nothing()));
0424       // Fill the matrix from the histogram content
0425       for (int ib0 = 1; ib0 <= nbins0; ++ib0) {
0426         for (int ib1 = 1; ib1 <= nbins1; ++ib1) {
0427           auto dt = static_cast<float>(t->GetBinContent(ib0, ib1));
0428           if (dt > 0.) {
0429             auto dx0 = static_cast<float>(x0->GetBinContent(ib0, ib1));
0430             auto dl0 = static_cast<float>(l0->GetBinContent(ib0, ib1));
0431             auto da = static_cast<float>(A->GetBinContent(ib0, ib1));
0432             auto dz = static_cast<float>(Z->GetBinContent(ib0, ib1));
0433             auto drho = static_cast<float>(rho->GetBinContent(ib0, ib1));
0434             // Create material properties
0435             const auto material =
0436                 Material::fromMassDensity(dx0, dl0, da, dz, drho);
0437             materialMatrix[ib1 - 1][ib0 - 1] = MaterialSlab(material, dt);
0438           }
0439         }
0440       }  // Construct the binned material with the right bin utility
0441       texturedSurfaceMaterial = std::make_shared<const BinnedSurfaceMaterial>(
0442           bUtility, std::move(materialMatrix));
0443     }
0444   } else {
0445     // Construct the names for histogram type storage
0446     std::string indexName = tdName + "/" + m_cfg.indexHistName;
0447     // Get the histograms
0448     auto ih = dynamic_cast<TH2I*>(rFile.Get(indexName.c_str()));
0449     if (ih != nullptr) {
0450       // Get the number of bins
0451       int nbins0 = ih->GetNbinsX();
0452       int nbins1 = ih->GetNbinsY();
0453       // The material matrix
0454       MaterialSlabMatrix materialMatrix(
0455           nbins1, MaterialSlabVector(nbins0, MaterialSlab::Nothing()));
0456       // Fill the matrix from the tree entries
0457       for (int ib0 = 1; ib0 <= nbins0; ++ib0) {
0458         for (int ib1 = 1; ib1 <= nbins1; ++ib1) {
0459           auto idx = static_cast<int>(ih->GetBinContent(ib0, ib1));
0460           indexedMaterialTree->GetEntry(idx);
0461           const auto material = Material::fromMassDensity(
0462               m_indexedMaterialTreePayload.hX0,
0463               m_indexedMaterialTreePayload.hL0, m_indexedMaterialTreePayload.hA,
0464               m_indexedMaterialTreePayload.hZ,
0465               m_indexedMaterialTreePayload.hRho);
0466           materialMatrix[ib1 - 1][ib0 - 1] =
0467               MaterialSlab(material, m_indexedMaterialTreePayload.ht);
0468         }
0469       }  // Construct the binned material with the right bin utility
0470       texturedSurfaceMaterial = std::make_shared<const BinnedSurfaceMaterial>(
0471           bUtility, std::move(materialMatrix));
0472     }
0473   }
0474 
0475   return texturedSurfaceMaterial;
0476 }