CbmRoot
Loading...
Searching...
No Matches
KfSetupBuilder.cxx
Go to the documentation of this file.
1/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Sergei Zharko [committer] */
4
9
10#include "KfSetupBuilder.h"
11
12#include <boost/filesystem.hpp>
13
14#include <numeric>
15
17
18namespace fs = boost::filesystem;
19
20// ---------------------------------------------------------------------------------------------------------------------
21//
23{
24 return fmt::format(
25 "GeoLayer: detId={}, locId={}, zRef={:9.4}cm, z=[{:9.4}, {:9.4}]cm, xFull=[{:9.4}, {:9.4}]cm, "
26 "yFull=[{:9.4, {:9.4}}]cm, xAct=[{:9.4}, {:9.4}]cm, yAct=[{:9.4}, {:9.4}]cm, fieldType={}, timeInfo={}",
28 static_cast<int>(fieldType), timeInfo);
29}
30
31// ---------------------------------------------------------------------------------------------------------------------
32//
34{
35 fbReady = false;
36 auto [itAdded, wasInserted] = fGeoLayers.insert(geoLayer);
37 if (!wasInserted) {
38 throw std::logic_error(fmt::format(
39 "SetupBuilder::AddLayer: attempt of adding a duplicating geometry layer: {}\n"
40 "The next layers were already added: {}",
41 itAdded->ToString(),
42 std::accumulate(fGeoLayers.begin(), fGeoLayers.end(), std::string{}, [](std::string s, const auto& l) {
43 return std::move(s) + "\n\t - " + std::move(l.ToString());
44 })));
45 }
46}
47
48
49// ---------------------------------------------------------------------------------------------------------------------
50//
52{
53 LOG(info) << "kf::SetupBuilder initialization: ...";
54
56 throw std::runtime_error("kf::SetupBuilder: no field is provided");
57 }
58 if (fbIfSetFromSetup) {
59 LOG(info) << "kf::SetupBuilder initialization: done";
60 fbReady = true;
61 return;
62 }
63 else {
64 if (fGeoLayers.size() == 0) {
65 throw std::runtime_error("kf::SetupBuilder: no geometry layers initialized");
66 }
67 if (!fpMaterialMapFactory.get()) {
68 throw std::runtime_error("kf::SetupBuilder: no material map factory provided");
69 }
70 if (!fbIfTargetSet) {
71 throw std::runtime_error("kf::SetupBuilder: target properties were not set");
72 }
73 }
74
75 bool bMaterialLoaded{false};
76 if (!fsMaterialCacheFile.empty()) {
77 bMaterialLoaded = this->LoadMaterial();
78 }
79
80 // Add material to the target:
81 if (!bMaterialLoaded) {
82 // Material budget
83 double zMin{fTarget.GetZ() + kTargetCenterOffset};
84 double zMax{fTarget.GetZ() + fTarget.GetDz() * kTargetMaterialOffset};
85 double rMax{fTarget.GetR() * kTargetMaterialTransverseSizeMargin};
86 fTarget.SetMaterial(
87 fpMaterialMapFactory->GenerateMaterialMap(fTarget.GetZ(), zMin, zMax, rMax, kTargetMaterialMapNofBins));
88 }
89
90 // Init geometry layers
91 {
92 // Estimate acceptance slope
93 double acceptanceSlope = -1.; // arbitrary negative value
94 for (const auto& layer : fGeoLayers) {
95 double xyMax = std::max(std::max(std::fabs(layer.xMaxFull), std::fabs(layer.xMinFull)),
96 std::max(std::fabs(layer.yMaxFull), std::fabs(layer.yMinFull)));
97 double tCurr = xyMax / (layer.zRef - fTarget.GetZ());
98 assert(tCurr > 0);
99 acceptanceSlope = std::max(acceptanceSlope, tCurr);
100 }
101
102 if (!bMaterialLoaded) {
103 fvMaterial.clear();
104 fvMaterial.reserve(fGeoLayers.size());
105 }
106 double zLast{fTarget.GetZ() + fTarget.GetDz() * kTargetMaterialOffset};
107 for (auto layerIt = fGeoLayers.cbegin(); layerIt != fGeoLayers.cend(); ++layerIt) {
108 double z1 = layerIt->zMax;
109 double z2 = z1;
110 if (std::next(layerIt) != fGeoLayers.cend()) {
111 z2 = std::next(layerIt)->zMin;
112 }
113 double zNew{0.5 * (z1 + z2)};
114 double xyMax{acceptanceSlope * (layerIt->zRef - fTarget.GetZ())};
115 if (!bMaterialLoaded) {
116 auto material{fpMaterialMapFactory->GenerateMaterialMap(layerIt->zRef, zLast, zNew, xyMax, fMatMapNofBins)};
117 fvMaterial.push_back(std::move(material));
118 }
119
120 // Note: square material maps to follow the material budget map regions
121 // TODO: test field xMax, xMin
122 double fieldXmax = std::max(std::fabs(layerIt->xMaxFull), std::fabs(layerIt->xMinFull));
123 double fieldYmax = std::max(std::fabs(layerIt->yMaxFull), std::fabs(layerIt->yMinFull));
124 fFieldBuilder.AddSliceReference(fieldXmax, fieldYmax, layerIt->zRef);
125 fModuleIndexFactory.AddComponent<int>(layerIt->detId, layerIt->locId, layerIt->zRef);
126 zLast = zNew;
127 }
128 }
129
130 if (!bMaterialLoaded && !fsMaterialCacheFile.empty()) {
131 this->StoreMaterial();
132 }
133
134 fbIfGeoLayersInit = true;
135 fbReady = true;
136 LOG(info) << "kf::SetupBuilder initialization: done";
137}
138
139// ---------------------------------------------------------------------------------------------------------------------
140//
142{
143 return fmt::format( //
144 "kf::SetupBuilder initialization: failed:" //
145 "\n - target property set: {}" //
146 "\n - geo layers added: {}" //
147 "\n - field function set: {}" //
148 "\n - set from setup: {}" //
149 "\n - material map creator set: {}", //
151}
152
153// ---------------------------------------------------------------------------------------------------------------------
154//
156{
157 auto path = fs::absolute(fs::weakly_canonical(fsMaterialCacheFile));
158
159 std::ifstream ifs(path.string(), std::ios::binary);
160 if (!ifs) { // File does not exist yet
161 return false;
162 }
163 try {
164 boost::archive::binary_iarchive ia(ifs);
165 MaterialMap targetMat;
166 size_t refHash;
167 ia >> refHash;
168 if (refHash != fGeoHash) {
169 LOG(warn) << "kf::SetupBuilder::LoadMaterial: reference hash from input file \"" << path.string()
170 << "\" "
171 "diverges from one, obtained from the actual detector setup geometry. Material budget will be "
172 "re-generated, and a new file will be created";
173 return false;
174 }
175 ia >> targetMat;
176 ia >> fvMaterial;
177 fTarget.SetMaterial(targetMat);
178 }
179 catch (const std::exception& err) {
180 LOG(warn) << "kf::SetupBuilder::LoadMaterial: input file \"" << path.string()
181 << "\" has inconsistent format "
182 "or was corrupted. The material maps will be re-generated";
183 return false;
184 }
185 LOG(info) << "kf::SetupBuilder::LoadMaterial: the material maps were loaded from cache file \"" << path.string()
186 << "\"";
187 return true;
188}
189
190// ---------------------------------------------------------------------------------------------------------------------
191//
193{
194 fbReady = false;
195 fbIfTargetSet = false;
196 fbIfGeoLayersInit = false;
197 fbIfFieldFunctionSet = false;
198 fbIfSetFromSetup = false;
199 fFieldBuilder.Reset();
200 fModuleIndexFactory.Reset();
201 fvMaterial.clear();
202 fGeoLayers.clear();
203 fpMaterialMapFactory = nullptr;
204}
205
206// ---------------------------------------------------------------------------------------------------------------------
207//
208void SetupBuilder::SetTargetProperty(double x, double y, double z, double dz, double r)
209{
210 fbReady = false;
211 fTarget.SetX(x);
212 fTarget.SetY(y);
213 fTarget.SetZ(z);
214 fTarget.SetDz(dz);
215 fTarget.SetR(r);
216 fFieldBuilder.SetTarget(x, y, z);
217 fbIfTargetSet = true;
218}
219
220// ---------------------------------------------------------------------------------------------------------------------
221//
222void SetupBuilder::Store(const Setup<double>& setup, const std::string& fileName)
223{
224 auto path = fs::absolute(fs::weakly_canonical(fileName));
225 fs::create_directories(path.parent_path());
226
227 std::ofstream ofs(path.string(), std::ios::binary);
228 if (!ofs) {
229 throw std::runtime_error(
230 fmt::format("kf::SetupBuilder::Store: failed opening file \"{}\" to store the setup", path.string()));
231 }
232 LOG(info) << "kf::SetupBuilder: writing setup into file \"" << path.string() << '\"';
233 boost::archive::binary_oarchive oa(ofs);
234 oa << setup;
235}
236
237// ---------------------------------------------------------------------------------------------------------------------
238//
240{
241 auto path = fs::absolute(fs::weakly_canonical(fsMaterialCacheFile));
242 fs::create_directories(path.parent_path());
243
244 std::ofstream ofs(path.string(), std::ios::binary);
245 if (!ofs) {
246 throw std::runtime_error(
247 fmt::format("kf::SetupBuilder::Store: failed opening file \"{}\" to store the material cache", path.string()));
248 }
249 boost::archive::binary_oarchive oa(ofs);
250 oa << fGeoHash;
251 oa << fTarget.GetMaterial();
252 oa << fvMaterial;
253}
A base KF-Setup initialization class (source)
A map of station thickness in units of radiation length (X0) to the specific point in XY plane.
Creates a valid initialized Setup instance.
void Reset()
Resets the instance.
int fMatMapNofBins
Number of bins in material maps.
std::string fsMaterialCacheFile
A cache file for the material.
std::set< LayerProperty > fGeoLayers
Set of geometrical layers.
static constexpr double kTargetMaterialOffset
Offset of the target material [in dz].
std::string InitStatusMsg() const
Prints initialization status message.
bool fbIfFieldFunctionSet
Field function initialized.
static constexpr double kTargetMaterialTransverseSizeMargin
Margin of target transverse size.
ModuleIndexMapFactory fModuleIndexFactory
Module index factory.
Target< double > fTarget
Target properties.
FieldBuilder fFieldBuilder
Instance of field factory.
bool fbIfGeoLayersInit
Geo layers initialized.
bool LoadMaterial()
Reads material from file.
void StoreMaterial() const
Stores material to file.
void Init()
Initializes, validates and caches the parameters.
void AddLayer(LayerProperty geoLayer)
Adds material layer.
void SetTargetProperty(double x, double y, double z, double dz, double r)
Sets target initialization properties.
static constexpr int kTargetMaterialMapNofBins
Number of bins along x- and y-axis in the target region;.
static constexpr double kTargetCenterOffset
Offset from target center [cm].
std::vector< MaterialMap > fvMaterial
Material map container.
bool fbIfTargetSet
Target initialized.
bool fbReady
Instance is ready for setup generation.
static void Store(const Setup< double > &setup, const std::string &fileName)
Stores a serialized setup to a file.
std::shared_ptr< IMaterialMapFactory > fpMaterialMapFactory
Material map creator.
size_t fGeoHash
A hash of the geometry.
KF-framework representation of the detector setup.
Definition KfSetup.h:37
std::string ToString() const
String representation of the class.
A helper structure to store geometrical information of the layers.
double xMaxAct
Upper x-coordinate boundary of active volume [cm].
bool timeInfo
If a layer stores time information.
double yMinAct
Lower x-coordinate boundary of active volume [cm].
double zMin
Lower z-coordinate boundary [cm].
int locId
Local index of the detector module.
double xMaxFull
Upper x-coordinate boundary of full volume [cm].
double yMinFull
Lower x-coordinate boundary of full volume [cm].
double zMax
Upper z-coordinate boundary [cm].
double zRef
Reference z-coordinate [cm].
EFieldType fieldType
Type of the magnetic field.
double xMinAct
Lower x-coordinate boundary of active volume [cm].
double xMinFull
Lower x-coordinate boundary of full volume [cm].
double yMaxFull
Upper x-coordinate boundary of full volume [cm].
double yMaxAct
Upper x-coordinate boundary of active volume [cm].