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, volumeMaps] = detMaterial;
53
54 // Write the surface material maps
55 ActsPlugins::RootMaterialMapIo accessor(accessorConfig,
56 makeActsAthenaLogger(this, "RootMaterialWriterTool"));
57
58 for (const auto& [geoId, sMap] : surfaceMaps) {
59 // Get the Surface material
60 accessor.write(*m_outputFile, geoId, *sMap, accessorOptions);
61 }
62
63 // Write the volume material maps
64 for (auto& [key, value] : volumeMaps) {
65 // Get the Volume material
66 const Acts::IVolumeMaterial* vMaterial = value.get();
67 if (vMaterial == nullptr) {
68 ATH_MSG_WARNING("No material for volume " << key << " skipping");
69 continue;
70 }
71
72 // get the geometry ID
73 Acts::GeometryIdentifier geoID = key;
74 // decode the geometryID
75 const auto gvolID = geoID.volume();
76
77 // create the directory
78 std::string tdName = accessorOptions.folderVolumeNameBase.c_str();
79 tdName += accessorConfig.volumePrefix + std::to_string(gvolID);
80
81 // create a new directory
82 m_outputFile->mkdir(tdName.c_str());
83 m_outputFile->cd(tdName.c_str());
84
85 ATH_MSG_VERBOSE("Writing out map at " << tdName);
86
87 // understand what sort of material you have in mind
88 auto bvMaterial3D = dynamic_cast<const Acts::InterpolatedMaterialMap<
89 Acts::MaterialMapLookup<Acts::MaterialGrid3D>>*>(vMaterial);
90 auto bvMaterial2D = dynamic_cast<const Acts::InterpolatedMaterialMap<
91 Acts::MaterialMapLookup<Acts::MaterialGrid2D>>*>(vMaterial);
92
93 int points = 1;
94 if (bvMaterial3D != nullptr || bvMaterial2D != nullptr) {
95 // Get the binning data
96 std::vector<Acts::BinningData> binningData;
97 if (bvMaterial3D != nullptr) {
98 binningData = bvMaterial3D->binUtility().binningData();
99 Acts::MaterialGrid3D grid = bvMaterial3D->getMapper().getGrid();
100 points = static_cast<int>(grid.size());
101 } else {
102 binningData = bvMaterial2D->binUtility().binningData();
103 Acts::MaterialGrid2D grid = bvMaterial2D->getMapper().getGrid();
104 points = static_cast<int>(grid.size());
105 }
106
107 // 2-D or 3-D maps
108 auto bins = static_cast<int>(binningData.size());
109 auto fBins = static_cast<float>(bins);
110
111 // The bin number information
112 TH1F n(accessorConfig.nBinsHistName.c_str(), "bins; bin", bins, -0.5, fBins - 0.5);
113
114 // The binning value information
115 TH1F v(accessorConfig.axisDirHistName.c_str(), "binning values; bin", bins, -0.5, fBins - 0.5);
116
117 // The binning option information
118 TH1F o(accessorConfig.axisBoundaryTypeHistName.c_str(), "binning options; bin", bins, -0.5, fBins - 0.5);
119
120 // The binning option information
121 TH1F rmin(accessorConfig.minRangeHistName.c_str(), "min; bin", bins, -0.5, fBins - 0.5);
122
123 // The binning option information
124 TH1F rmax(accessorConfig.maxRangeHistName.c_str(), "max; bin", bins, -0.5, fBins - 0.5);
125
126 // Now fill the histogram content
127 for (const auto& [b, bData] : enumerate(binningData)) {
128 // Fill: nbins, value, option, min, max
129 n.SetBinContent(static_cast<int>(b), static_cast<int>(binningData[b - 1].bins()));
130 v.SetBinContent(static_cast<int>(b), static_cast<int>(binningData[b - 1].binvalue));
131 o.SetBinContent(static_cast<int>(b), static_cast<int>(binningData[b - 1].option));
132 rmin.SetBinContent(static_cast<int>(b), binningData[b - 1].min);
133 rmax.SetBinContent(static_cast<int>(b), binningData[b - 1].max);
134 }
135 n.Write();
136 v.Write();
137 o.Write();
138 rmin.Write();
139 rmax.Write();
140 }
141
142 auto fPoints = static_cast<float>(points);
143 TH1F x0(accessorConfig.x0HistName.c_str(), "X_{0} [mm] ;gridPoint", points, -0.5, fPoints - 0.5);
144 TH1F l0(accessorConfig.l0HistName.c_str(), "#Lambda_{0} [mm] ;gridPoint", points, -0.5, fPoints - 0.5);
145 TH1F A(accessorConfig.aHistName.c_str(), "X_{0} [mm] ;gridPoint", points, -0.5, fPoints - 0.5);
146 TH1F Z(accessorConfig.zHistName.c_str(), "#Lambda_{0} [mm] ;gridPoint", points, -0.5, fPoints - 0.5);
147 TH1F rho(accessorConfig.rhoHistName.c_str(), "#rho [g/mm^3] ;gridPoint", points, -0.5, fPoints - 0.5);
148 // homogeneous volume
149 if (points == 1) {
150 auto mat = vMaterial->material({0, 0, 0});
151 x0.SetBinContent(1, mat.X0());
152 l0.SetBinContent(1, mat.L0());
153 A.SetBinContent(1, mat.Ar());
154 Z.SetBinContent(1, mat.Z());
155 rho.SetBinContent(1, mat.massDensity());
156 } else {
157 // 3d grid volume
158 if (bvMaterial3D != nullptr) {
159 Acts::MaterialGrid3D grid = bvMaterial3D->getMapper().getGrid();
160 for (int point = 0; point < points; point++) {
161 auto mat = Acts::Material(grid.at(point));
162 if (!mat.isVacuum()) {
163 x0.SetBinContent(point + 1, mat.X0());
164 l0.SetBinContent(point + 1, mat.L0());
165 A.SetBinContent(point + 1, mat.Ar());
166 Z.SetBinContent(point + 1, mat.Z());
167 rho.SetBinContent(point + 1, mat.massDensity());
168 }
169 }
170 }
171 // 2d grid volume
172 else if (bvMaterial2D != nullptr) {
173 Acts::MaterialGrid2D grid = bvMaterial2D->getMapper().getGrid();
174 for (int point = 0; point < points; point++) {
175 auto mat = Acts::Material(grid.at(point));
176 if (!mat.isVacuum()) {
177 x0.SetBinContent(point + 1, mat.X0());
178 l0.SetBinContent(point + 1, mat.L0());
179 A.SetBinContent(point + 1, mat.Ar());
180 Z.SetBinContent(point + 1, mat.Z());
181 rho.SetBinContent(point + 1, mat.massDensity());
182 }
183 }
184 }
185 }
186 x0.Write();
187 l0.Write();
188 A.Write();
189 Z.Write();
190 rho.Write();
191 }
192
193 return;
194}
195
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(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)
#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