41 #include <boost/algorithm/string.hpp>
42 #include <boost/algorithm/string/finder.hpp>
43 #include <boost/algorithm/string/iter_find.hpp>
58 for (
unsigned i = 0; i < material.
parameters().size(); ++i) {
69 Acts::Material::ParametersVector::Zero();
70 for (
auto i = params.size(); 0 < i--;) {
72 params[i] = encoded.
at(i);
83 {
"material", encodeMaterial(slab.
material())},
90 encoded.
at(
"thickness").
get<
float>());
97 : m_cfg(std::move(cfg)) {
100 throw std::invalid_argument(
"Missing logger");
105 std::shared_ptr<const Acts::ISurfaceMaterial>>,
106 std::map<Acts::GeometryIdentifier,
107 std::shared_ptr<const Acts::IVolumeMaterial>>>
109 auto& j = materialmaps;
111 std::pair<SurfaceMaterialMap, VolumeMaterialMap> maps;
112 ACTS_VERBOSE(
"j2a: Reading material maps from json file.");
113 ACTS_VERBOSE(
"j2a: Found entries for " << j.count(m_cfg.volkey)
116 for (
auto& [key,
value] : j.items()) {
118 if (key == m_cfg.volkey) {
121 for (
auto& [vkey, vvalue] : volj.items()) {
123 int vid = std::stoi(vkey);
124 Acts::GeometryIdentifier volumeID;
128 for (
auto& [vckey, vcvalue] : vvalue.items()) {
129 if (vckey == m_cfg.boukey and m_cfg.processBoundaries and
130 not vcvalue.empty()) {
131 ACTS_VERBOSE(
"j2a: --> BoundarySurface(s) to be parsed");
132 for (
auto& [bkey, bvalue] : vcvalue.items()) {
134 int bid = std::stoi(bkey);
135 Acts::GeometryIdentifier boundaryID(volumeID);
137 ACTS_VERBOSE(
"j2a: ---> Found boundary surface " << bid);
138 if (bvalue[m_cfg.mapkey] ==
true) {
139 auto boumat = jsonToSurfaceMaterial(bvalue);
140 maps.first[boundaryID] =
141 std::shared_ptr<const ISurfaceMaterial>(boumat);
144 }
else if (vckey == m_cfg.laykey) {
148 for (
auto& [lkey, lvalue] : layj.items()) {
150 int lid = std::stoi(lkey);
151 Acts::GeometryIdentifier layerID(volumeID);
155 for (
auto& [lckey, lcvalue] : lvalue.items()) {
156 if (lckey == m_cfg.repkey and m_cfg.processRepresenting and
157 not lcvalue.empty()) {
159 if (lcvalue[m_cfg.mapkey] ==
true) {
160 auto repmat = jsonToSurfaceMaterial(lcvalue);
161 maps.first[layerID] =
162 std::shared_ptr<const Acts::ISurfaceMaterial>(repmat);
164 }
else if (lckey == m_cfg.appkey and m_cfg.processApproaches and
165 not lcvalue.empty()) {
168 for (
auto& [askey, asvalue] : lcvalue.items()) {
170 int aid = (askey ==
"*") ? 0 : std::stoi(askey);
171 Acts::GeometryIdentifier approachID(layerID);
174 if (asvalue[m_cfg.mapkey] ==
true) {
175 auto appmat = jsonToSurfaceMaterial(asvalue);
176 maps.first[approachID] =
177 std::shared_ptr<const Acts::ISurfaceMaterial>(appmat);
180 }
else if (lckey == m_cfg.senkey and m_cfg.processSensitives and
181 not lcvalue.empty()) {
184 for (
auto& [sskey, ssvalue] : lcvalue.items()) {
186 int sid = (sskey ==
"*") ? 0 : std::stoi(sskey);
187 Acts::GeometryIdentifier senisitiveID(layerID);
189 ACTS_VERBOSE(
"j2a: -----> Sensitive surface " << sskey);
190 if (ssvalue[m_cfg.mapkey] ==
true) {
191 auto senmat = jsonToSurfaceMaterial(ssvalue);
192 maps.first[senisitiveID] =
193 std::shared_ptr<const Acts::ISurfaceMaterial>(senmat);
200 }
else if (m_cfg.processVolumes and vckey == m_cfg.matkey and
201 not vcvalue.empty()) {
203 if (vcvalue[m_cfg.mapkey] ==
true) {
204 auto intermat = jsonToVolumeMaterial(vcvalue);
205 maps.second[volumeID] =
206 std::shared_ptr<const Acts::IVolumeMaterial>(intermat);
211 }
else if (key == m_cfg.geoversion) {
226 for (
auto& [key,
value] : maps.first) {
228 auto volRep = detRep.
volumes.find(vid);
229 if (volRep == detRep.
volumes.end()) {
231 volRep = detRep.
volumes.find(vid);
232 volRep->second.volumeID = key;
237 auto layRep = volRep->second.layers.find(lid);
238 if (layRep == volRep->second.layers.end()) {
239 volRep->second.layers.insert({lid,
LayerRep()});
240 layRep = volRep->second.layers.find(lid);
241 layRep->second.layerID = key;
247 layRep->second.sensitives.insert({sid,
value.get()});
248 }
else if (aid != 0) {
249 layRep->second.approaches.insert({aid,
value.get()});
251 layRep->second.representing =
value.get();
257 volRep->second.boundaries.insert({bid,
value.get()});
260 for (
auto& [key,
value] : maps.second) {
263 auto volRep = detRep.
volumes.find(vid);
264 if (volRep == detRep.
volumes.end()) {
266 volRep = detRep.
volumes.find(vid);
267 volRep->second.volumeID = key;
269 volRep->second.material =
value.get();
272 return detectorRepToJson(detRep);
278 ACTS_VERBOSE(
"a2j: Writing json from detector representation");
286 volj[m_cfg.namekey] =
value.volumeName;
287 std::ostringstream svolumeID;
288 svolumeID <<
value.volumeID;
289 volj[m_cfg.geometryidkey] = svolumeID.str();
290 if (m_cfg.processVolumes &&
value.material) {
291 volj[m_cfg.matkey] = volumeMaterialToJson(*
value.material);
294 if (not
value.layers.empty()) {
297 for (
auto& [lkey, lvalue] :
value.layers) {
300 std::ostringstream slayerID;
301 slayerID << lvalue.layerID;
302 layj[m_cfg.geometryidkey] = slayerID.str();
304 if (not lvalue.approaches.empty() and m_cfg.processApproaches) {
305 ACTS_VERBOSE(
"a2j: -----> Found " << lvalue.approaches.size()
306 <<
" approach surface(s)");
308 for (
auto& [akey, avalue] : lvalue.approaches) {
309 ACTS_VERBOSE(
"a2j: ------> Convert approach surface " << akey);
310 approachesj[
std::to_string(akey)] = surfaceMaterialToJson(*avalue);
311 if (lvalue.approacheSurfaces.find(akey) !=
312 lvalue.approacheSurfaces.end())
314 lvalue.approacheSurfaces.at(akey));
317 layj[m_cfg.appkey] = approachesj;
320 if (not lvalue.sensitives.empty() and m_cfg.processSensitives) {
321 ACTS_VERBOSE(
"a2j: -----> Found " << lvalue.sensitives.size()
322 <<
" sensitive surface(s)");
324 for (
auto& [skey, svalue] : lvalue.sensitives) {
325 ACTS_VERBOSE(
"a2j: ------> Convert sensitive surface " << skey);
326 sensitivesj[
std::to_string(skey)] = surfaceMaterialToJson(*svalue);
327 if (lvalue.sensitiveSurfaces.find(skey) !=
328 lvalue.sensitiveSurfaces.end())
330 lvalue.sensitiveSurfaces.at(skey));
333 layj[m_cfg.senkey] = sensitivesj;
336 if (lvalue.representing !=
nullptr and m_cfg.processRepresenting) {
337 ACTS_VERBOSE(
"a2j: ------> Convert representing surface ");
338 layj[m_cfg.repkey] = surfaceMaterialToJson(*lvalue.representing);
339 if (lvalue.representingSurface !=
nullptr)
340 addSurfaceToJson(layj[m_cfg.repkey], lvalue.representingSurface);
344 volj[m_cfg.laykey] = layersj;
347 if (not
value.boundaries.empty()) {
349 <<
" boundary/ies ");
351 for (
auto& [bkey, bvalue] :
value.boundaries) {
353 boundariesj[
std::to_string(bkey)] = surfaceMaterialToJson(*bvalue);
354 if (
value.boundarySurfaces.find(bkey) !=
value.boundarySurfaces.end())
356 value.boundarySurfaces.at(bkey));
358 volj[m_cfg.boukey] = boundariesj;
364 detectorj[m_cfg.volkey] = volumesj;
376 if (key == m_cfg.transfokeys and not
value.empty()) {
386 if (key == m_cfg.bin0key and not
value.empty()) {
387 bUtility += jsonToBinUtility(
value);
388 }
else if (key == m_cfg.bin1key and not
value.empty()) {
389 bUtility += jsonToBinUtility(
value);
391 if (key == m_cfg.datakey and not
value.empty()) {
392 mpMatrix = jsonToMaterialMatrix(
value);
397 if (mpMatrix.empty()) {
399 }
else if (bUtility.
bins() == 1) {
410 const json& material) {
415 if (key == m_cfg.transfokeys and not
value.empty()) {
421 std::vector<Material> mmat;
425 if (key == m_cfg.bin0key and not
value.empty()) {
426 bUtility += jsonToBinUtility(
value);
427 }
else if (key == m_cfg.bin1key and not
value.empty()) {
428 bUtility += jsonToBinUtility(
value);
429 }
else if (key == m_cfg.bin2key and not
value.empty()) {
430 bUtility += jsonToBinUtility(
value);
432 if (key == m_cfg.datakey and not
value.empty()) {
433 for (
const auto& bin :
value) {
434 mmat.push_back(decodeMaterial(bin));
442 }
else if (mmat.size() == 1) {
446 std::function<Acts::Vector2D(Acts::Vector3D)> transfoGlobalToLocal;
459 for (
size_t bin = 0; bin < mmat.size(); bin++) {
460 mGrid.
at(bin) = mmat[bin].parameters();
465 std::move(matMap), bUtility);
467 std::function<Acts::Vector3D(Acts::Vector3D)> transfoGlobalToLocal;
481 for (
size_t bin = 0; bin < mmat.size(); bin++) {
482 mGrid.
at(bin) = mmat[bin].parameters();
487 std::move(matMap), bUtility);
498 return detectorRepToJson(detRep);
511 for (
auto& vol : volumes) {
513 convertToRep(detRep, *vol);
517 if (m_cfg.processDenseVolumes && !tVolume.
denseVolumes().empty()) {
521 convertToRep(detRep, *vol);
525 Acts::GeometryIdentifier volumeID = tVolume.
geometryId();
531 }
else if (m_cfg.processnonmaterial ==
true) {
541 for (
auto& lay : layers) {
542 auto layRep = convertToRep(*lay);
545 Acts::GeometryIdentifier layerID = lay->geometryId();
547 volRep.
layers.insert({lid, std::move(layRep)});
554 auto& bssfRep = bsurf->surfaceRepresentation();
555 if (bssfRep.surfaceMaterial() !=
nullptr) {
556 Acts::GeometryIdentifier boundaryID = bssfRep.geometryId();
560 volRep.
boundaries[bid] = bssfRep.surfaceMaterial();
563 }
else if (m_cfg.processnonmaterial ==
true) {
566 Acts::GeometryIdentifier boundaryID = bssfRep.geometryId();
579 detRep.
volumes.insert({vid, std::move(volRep)});
589 if (m_cfg.processSensitives and tLayer.
surfaceArray() !=
nullptr) {
591 if (ssf !=
nullptr && ssf->surfaceMaterial() !=
nullptr) {
592 Acts::GeometryIdentifier sensitiveID = ssf->geometryId();
594 layRep.
sensitives.insert({sid, ssf->surfaceMaterial()});
596 }
else if (m_cfg.processnonmaterial ==
true) {
599 Acts::GeometryIdentifier sensitiveID = ssf->geometryId();
614 }
else if (m_cfg.processnonmaterial ==
true) {
628 if (asf->surfaceMaterial() !=
nullptr) {
629 Acts::GeometryIdentifier approachID = asf->
geometryId();
631 layRep.
approaches.insert({aid, asf->surfaceMaterial()});
633 }
else if (m_cfg.processnonmaterial ==
true) {
636 Acts::GeometryIdentifier approachID = asf->geometryId();
657 if (psMaterial !=
nullptr) {
659 smj[m_cfg.typekey] =
"proto";
661 smj[m_cfg.mapkey] =
false;
662 bUtility = &(psMaterial->binUtility());
667 if (hsMaterial !=
nullptr) {
669 smj[m_cfg.typekey] =
"homogeneous";
670 smj[m_cfg.mapkey] =
true;
671 if (m_cfg.writeData) {
674 encodeMaterialSlab(hsMaterial->materialSlab(0, 0)),
682 if (bsMaterial !=
nullptr) {
684 smj[m_cfg.typekey] =
"binned";
685 smj[m_cfg.mapkey] =
true;
686 bUtility = &(bsMaterial->binUtility());
689 if (m_cfg.writeData) {
691 for (
const auto& mpVector : bsMaterial->fullMaterial()) {
693 for (
const auto& mp : mpVector) {
698 smj[m_cfg.datakey] = std::move(mmat);
704 if (bUtility !=
nullptr && !bUtility->
binningData().empty()) {
705 std::vector<std::string> binkeys = {m_cfg.bin0key, m_cfg.bin1key};
709 for (
size_t ibin = 0; ibin < binningData.size(); ++ibin) {
711 auto cbData = binningData[ibin];
721 if (smj[m_cfg.typekey] ==
"proto" && cbData.bins() > 1)
722 smj[m_cfg.mapkey] =
true;
724 if (smj[m_cfg.typekey] !=
"proto") {
725 std::pair<double, double> minMax = {cbData.min, cbData.max};
728 smj[binkeys[ibin]] = binj;
730 std::vector<double> transfo;
732 if (not transfo_matrix.isApprox(Acts::Transform3D::Identity())) {
733 for (
int i = 0; i < 4; i++) {
734 for (
int j = 0; j < 4; j++) {
735 transfo.push_back(transfo_matrix(j, i));
738 smj[m_cfg.transfokeys] = transfo;
751 if (pvMaterial !=
nullptr) {
753 smj[m_cfg.typekey] =
"proto";
755 smj[m_cfg.mapkey] =
false;
756 bUtility = &(pvMaterial->binUtility());
761 if (hvMaterial !=
nullptr) {
763 smj[m_cfg.typekey] =
"homogeneous";
764 smj[m_cfg.mapkey] =
true;
765 if (m_cfg.writeData) {
768 encodeMaterial(hvMaterial->material({0, 0, 0})),
773 auto bvMaterial2D =
dynamic_cast<
777 if (bvMaterial2D !=
nullptr) {
779 smj[m_cfg.typekey] =
"interpolated2D";
780 smj[m_cfg.mapkey] =
true;
781 bUtility = &(bvMaterial2D->binUtility());
783 if (m_cfg.writeData) {
786 for (
size_t bin = 0; bin < grid.
size(); bin++) {
789 smj[m_cfg.datakey] = std::move(mmat);
796 if (bvMaterial3D !=
nullptr) {
798 smj[m_cfg.typekey] =
"interpolated3D";
799 smj[m_cfg.mapkey] =
true;
800 bUtility = &(bvMaterial3D->binUtility());
802 if (m_cfg.writeData) {
805 for (
size_t bin = 0; bin < grid.
size(); bin++) {
808 smj[m_cfg.datakey] = std::move(mmat);
815 if (bUtility !=
nullptr && !bUtility->
binningData().empty()) {
816 std::vector<std::string> binkeys = {m_cfg.bin0key, m_cfg.bin1key,
821 for (
size_t ibin = 0; ibin < binningData.size(); ++ibin) {
823 auto cbData = binningData[ibin];
833 if (smj[m_cfg.typekey] ==
"proto" && cbData.bins() > 1)
834 smj[m_cfg.mapkey] =
true;
836 if (smj[m_cfg.typekey] !=
"proto") {
837 std::pair<double, double> minMax = {cbData.min, cbData.max};
840 smj[binkeys[ibin]] = binj;
842 std::vector<double> transfo;
844 for (
int i = 0; i < 4; i++) {
845 for (
int j = 0; j < 4; j++) {
846 transfo.push_back(transfo_matrix(j, i));
849 smj[m_cfg.transfokeys] = transfo;
857 std::ostringstream SurfaceID;
859 sjson[m_cfg.surfacegeometryidkey] = SurfaceID.str();
872 if (radialBounds !=
nullptr) {
873 sjson[m_cfg.surfacetypekey] =
"Disk";
874 sjson[m_cfg.surfacepositionkey] = sTransform.translation().z();
875 sjson[m_cfg.surfacerangekey] = {radialBounds->
rMin(), radialBounds->
rMax()};
877 if (cylinderBounds !=
nullptr) {
878 sjson[m_cfg.surfacetypekey] =
"Cylinder";
880 sjson[m_cfg.surfacerangekey] = {
884 if (annulusBounds !=
nullptr) {
885 sjson[m_cfg.surfacetypekey] =
"Annulus";
886 sjson[m_cfg.surfacepositionkey] = sTransform.translation().z();
887 sjson[m_cfg.surfacerangekey] = {
888 {annulusBounds->
rMin(), annulusBounds->
rMax()},
898 for (
auto& outer : data) {
900 for (
auto& inner : outer) {
901 mpVector.emplace_back(decodeMaterialSlab(inner));
903 mpMatrix.push_back(std::move(mpVector));
911 if (bin.
size() >= 3) {
918 unsigned int bins = bin[2];
921 if (bin.
size() >= 4 && bin[3].
size() == 2) {
932 const json& transfo) {
936 for (
auto& element : transfo) {
961 if (radialBounds !=
nullptr) {
976 if (cylinderBounds !=
nullptr) {
993 if (annulusBounds !=
nullptr) {
1001 if (rectangleBounds !=
nullptr) {
1011 "No corresponding bound found for the surface : " << surface.
name());
1026 if (cyBounds !=
nullptr) {
1043 if (cutcylBounds !=
nullptr) {
1054 }
else if (cuBounds !=
nullptr) {
1067 "No corresponding bound found for the volume : " << volume.
volumeName());