ATLAS Offline Software
Loading...
Searching...
No Matches
RootMaterialWriterTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
7#include "ActsPlugins/Root/RootMaterialMapIo.hpp"
8#include "Acts/Material/InterpolatedMaterialMap.hpp"
9#include "Acts/Material/MaterialGridHelper.hpp"
10
11#include <TFile.h>
12#include <TH1.h>
13#include <TH2.h>
14
16 const std::string& name,
17 const IInterface* parent)
18 : base_class(type, name, parent)
19{
20}
21
23{
24 if (m_outputFile != nullptr)
25 m_outputFile->Close();
26}
27
29{
30 // Setup ROOT I/O
31 m_outputFile = TFile::Open(m_fileName.value().c_str(), "RECREATE");
32 if (m_outputFile == nullptr) {
33 ATH_MSG_ERROR("Could not open '" + m_fileName + "'");
34 return StatusCode::FAILURE;
35 }
36
37 return StatusCode::SUCCESS;
38}
39
40
42 const Acts::TrackingGeometryMaterial& detMaterial) const
43{
45 ActsPlugins::RootMaterialMapIo::Config accessorConfig;
47 ActsPlugins::RootMaterialMapIo::Options accessorOptions;
48
49 // Change to the output file
50 m_outputFile->cd();
51
52 const auto& surfaceMaps = detMaterial.surfaceMaterials;
53 const auto& volumeMaps = detMaterial.volumeMaterials;
54 if (!detMaterial.keyedSurfaces.empty()) {
55 ATH_MSG_WARNING("Skipping " << detMaterial.keyedSurfaces.size()
56 << " keyed surface material maps, which are not supported");
57 }
58
59 // Write the surface material maps
60 ActsPlugins::RootMaterialMapIo accessor(accessorConfig,
61 makeActsAthenaLogger(this, "RootMaterialWriterTool"));
62
63 for (const auto& [geoId, sMap] : surfaceMaps) {
64 // Get the Surface material
65 accessor.write(*m_outputFile, geoId, *sMap, accessorOptions);
66 }
67
68 // Write the volume material maps
69 for (auto& [key, value] : volumeMaps) {
70 // Get the Volume material
71 const Acts::IVolumeMaterial* vMaterial = value.get();
72 if (vMaterial == nullptr) {
73 ATH_MSG_WARNING("No material for volume " << key << " skipping");
74 continue;
75 }
76
77 // get the geometry ID
78 Acts::GeometryIdentifier geoID = key;
79 // decode the geometryID
80 const auto gvolID = geoID.volume();
81
82 // create the directory
83 std::string tdName = accessorOptions.folderVolumeNameBase.c_str();
84 tdName += accessorConfig.volumePrefix + std::to_string(gvolID);
85
86 // create a new directory
87 m_outputFile->mkdir(tdName.c_str());
88 m_outputFile->cd(tdName.c_str());
89
90 ATH_MSG_VERBOSE("Writing out map at " << tdName);
91
92 // understand what sort of material you have in mind
93 auto bvMaterial3D = dynamic_cast<const Acts::InterpolatedMaterialMap<
94 Acts::MaterialMapLookup<Acts::MaterialGrid3D>>*>(vMaterial);
95 auto bvMaterial2D = dynamic_cast<const Acts::InterpolatedMaterialMap<
96 Acts::MaterialMapLookup<Acts::MaterialGrid2D>>*>(vMaterial);
97
98 int points = 1;
99 if (bvMaterial3D != nullptr || bvMaterial2D != nullptr) {
100 // Get the binning data
101 std::vector<Acts::BinningData> binningData;
102 if (bvMaterial3D != nullptr) {
103 binningData = bvMaterial3D->binUtility().binningData();
104 Acts::MaterialGrid3D grid = bvMaterial3D->getMapper().getGrid();
105 points = static_cast<int>(grid.size());
106 } else {
107 binningData = bvMaterial2D->binUtility().binningData();
108 Acts::MaterialGrid2D grid = bvMaterial2D->getMapper().getGrid();
109 points = static_cast<int>(grid.size());
110 }
111
112 // 2-D or 3-D maps
113 auto bins = static_cast<int>(binningData.size());
114 auto fBins = static_cast<float>(bins);
115
116 // The bin number information
117 TH1F n(accessorConfig.nBinsHistName.c_str(), "bins; bin", bins, -0.5, fBins - 0.5);
118
119 // The binning value information
120 TH1F v(accessorConfig.axisDirHistName.c_str(), "binning values; bin", bins, -0.5, fBins - 0.5);
121
122 // The binning option information
123 TH1F o(accessorConfig.axisBoundaryTypeHistName.c_str(), "binning options; bin", bins, -0.5, fBins - 0.5);
124
125 // The binning option information
126 TH1F rmin(accessorConfig.minRangeHistName.c_str(), "min; bin", bins, -0.5, fBins - 0.5);
127
128 // The binning option information
129 TH1F rmax(accessorConfig.maxRangeHistName.c_str(), "max; bin", bins, -0.5, fBins - 0.5);
130
131 // Now fill the histogram content
132 for (const auto [b, bData] : enumerate(binningData)) {
133 // Fill: nbins, value, option, min, max
134 n.SetBinContent(static_cast<int>(b), static_cast<int>(binningData[b - 1].bins()));
135 v.SetBinContent(static_cast<int>(b), static_cast<int>(binningData[b - 1].binvalue));
136 o.SetBinContent(static_cast<int>(b), static_cast<int>(binningData[b - 1].option));
137 rmin.SetBinContent(static_cast<int>(b), binningData[b - 1].min);
138 rmax.SetBinContent(static_cast<int>(b), binningData[b - 1].max);
139 }
140 n.Write();
141 v.Write();
142 o.Write();
143 rmin.Write();
144 rmax.Write();
145 }
146
147 auto fPoints = static_cast<float>(points);
148 TH1F x0(accessorConfig.x0HistName.c_str(), "X_{0} [mm] ;gridPoint", points, -0.5, fPoints - 0.5);
149 TH1F l0(accessorConfig.l0HistName.c_str(), "#Lambda_{0} [mm] ;gridPoint", points, -0.5, fPoints - 0.5);
150 TH1F A(accessorConfig.aHistName.c_str(), "X_{0} [mm] ;gridPoint", points, -0.5, fPoints - 0.5);
151 TH1F Z(accessorConfig.zHistName.c_str(), "#Lambda_{0} [mm] ;gridPoint", points, -0.5, fPoints - 0.5);
152 TH1F rho(accessorConfig.rhoHistName.c_str(), "#rho [g/mm^3] ;gridPoint", points, -0.5, fPoints - 0.5);
153 // homogeneous volume
154 if (points == 1) {
155 auto mat = vMaterial->material({0, 0, 0});
156 x0.SetBinContent(1, mat.X0());
157 l0.SetBinContent(1, mat.L0());
158 A.SetBinContent(1, mat.Ar());
159 Z.SetBinContent(1, mat.Z());
160 rho.SetBinContent(1, mat.massDensity());
161 } else {
162 // 3d grid volume
163 if (bvMaterial3D != nullptr) {
164 Acts::MaterialGrid3D grid = bvMaterial3D->getMapper().getGrid();
165 for (int point = 0; point < points; point++) {
166 auto mat = Acts::Material(grid.at(point));
167 if (!mat.isVacuum()) {
168 x0.SetBinContent(point + 1, mat.X0());
169 l0.SetBinContent(point + 1, mat.L0());
170 A.SetBinContent(point + 1, mat.Ar());
171 Z.SetBinContent(point + 1, mat.Z());
172 rho.SetBinContent(point + 1, mat.massDensity());
173 }
174 }
175 }
176 // 2d grid volume
177 else if (bvMaterial2D != nullptr) {
178 Acts::MaterialGrid2D grid = bvMaterial2D->getMapper().getGrid();
179 for (int point = 0; point < points; point++) {
180 auto mat = Acts::Material(grid.at(point));
181 if (!mat.isVacuum()) {
182 x0.SetBinContent(point + 1, mat.X0());
183 l0.SetBinContent(point + 1, mat.L0());
184 A.SetBinContent(point + 1, mat.Ar());
185 Z.SetBinContent(point + 1, mat.Z());
186 rho.SetBinContent(point + 1, mat.massDensity());
187 }
188 }
189 }
190 }
191 x0.Write();
192 l0.Write();
193 A.Write();
194 Z.Write();
195 rho.Write();
196 }
197
198 return;
199}
200
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
static const std::vector< std::string > bins
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
Definition Logger.cxx:64
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
virtual StatusCode initialize() override
RootMaterialWriterTool(const std::string &type, const std::string &name, const IInterface *parent)
Gaudi::Property< std::string > m_fileName
The name of the output file.
virtual void writeMaterial(const ActsTrk::GeometryContext &gctx, const Acts::TrackingGeometryMaterial &detMaterial) const override
hold the test vectors and ease the comparison