11 #include <boost/algorithm/string.hpp>
12 #include <boost/algorithm/string/finder.hpp>
13 #include <boost/algorithm/string/iter_find.hpp>
46 : m_cfg(std::move(cfg)) {
49 throw std::invalid_argument(
"Missing logger");
54 std::map<Acts::GeometryID, std::shared_ptr<const Acts::ISurfaceMaterial>>,
55 std::map<Acts::GeometryID, std::shared_ptr<const Acts::IVolumeMaterial>>>
57 auto& j = materialmaps;
59 std::pair<SurfaceMaterialMap, VolumeMaterialMap> maps;
60 ACTS_VERBOSE(
"j2a: Reading material maps from json file.");
61 ACTS_VERBOSE(
"j2a: Found entries for " << j.count(m_cfg.volkey)
64 for (
auto& [key,
value] : j.items()) {
66 if (key == m_cfg.volkey) {
69 for (
auto& [vkey, vvalue] : volj.items()) {
71 int vid = std::stoi(vkey);
76 for (
auto& [vckey, vcvalue] : vvalue.items()) {
77 if (vckey == m_cfg.boukey and m_cfg.processBoundaries and
78 not vcvalue.empty()) {
79 ACTS_VERBOSE(
"j2a: --> BoundarySurface(s) to be parsed");
80 for (
auto& [bkey, bvalue] : vcvalue.items()) {
82 int bid = std::stoi(bkey);
85 ACTS_VERBOSE(
"j2a: ---> Found boundary surface " << bid);
86 auto boumat = jsonToSurfaceMaterial(bvalue);
87 if (bvalue[m_cfg.mapkey] ==
true)
88 maps.first[boundaryID] =
89 std::shared_ptr<const ISurfaceMaterial>(boumat);
91 }
else if (vckey == m_cfg.laykey) {
95 for (
auto& [lkey, lvalue] : layj.items()) {
97 int lid = std::stoi(lkey);
102 for (
auto& [lckey, lcvalue] : lvalue.items()) {
103 if (lckey == m_cfg.repkey and m_cfg.processRepresenting and
104 not lcvalue.empty()) {
106 auto repmat = jsonToSurfaceMaterial(lcvalue);
107 if (lcvalue[m_cfg.mapkey] ==
true)
108 maps.first[layerID] =
109 std::shared_ptr<const Acts::ISurfaceMaterial>(repmat);
110 }
else if (lckey == m_cfg.appkey and m_cfg.processApproaches and
111 not lcvalue.empty()) {
114 for (
auto& [askey, asvalue] : lcvalue.items()) {
116 int aid = (askey ==
"*") ? 0 : std::stoi(askey);
120 auto appmat = jsonToSurfaceMaterial(asvalue);
121 if (asvalue[m_cfg.mapkey] ==
true)
122 maps.first[approachID] =
123 std::shared_ptr<const Acts::ISurfaceMaterial>(appmat);
125 }
else if (lckey == m_cfg.senkey and m_cfg.processSensitives and
126 not lcvalue.empty()) {
129 for (
auto& [sskey, ssvalue] : lcvalue.items()) {
131 int sid = (sskey ==
"*") ? 0 : std::stoi(sskey);
134 ACTS_VERBOSE(
"j2a: -----> Sensitive surface " << sskey);
135 auto senmat = jsonToSurfaceMaterial(ssvalue);
136 if (ssvalue[m_cfg.mapkey] ==
true)
137 maps.first[senisitiveID] =
138 std::shared_ptr<const Acts::ISurfaceMaterial>(senmat);
144 }
else if (vckey == m_cfg.matkey and not vcvalue.empty()) {
146 auto intermat = jsonToVolumeMaterial(vcvalue);
147 if (vcvalue[m_cfg.mapkey] ==
true) {
148 maps.second[volumeID] =
149 std::shared_ptr<const Acts::IVolumeMaterial>(intermat);
154 }
else if (key == m_cfg.geoversion) {
169 for (
auto& [key,
value] : maps.first) {
171 auto volRep = detRep.
volumes.find(vid);
172 if (volRep == detRep.
volumes.end()) {
174 volRep = detRep.
volumes.find(vid);
175 volRep->second.volumeID = key;
180 auto layRep = volRep->second.layers.find(lid);
181 if (layRep == volRep->second.layers.end()) {
182 volRep->second.layers.insert({lid,
LayerRep()});
183 layRep = volRep->second.layers.find(lid);
184 layRep->second.layerID = key;
190 layRep->second.sensitives.insert({sid,
value.get()});
191 }
else if (aid != 0) {
192 layRep->second.approaches.insert({aid,
value.get()});
194 layRep->second.representing =
value.get();
200 volRep->second.boundaries.insert({bid,
value.get()});
203 for (
auto& [key,
value] : maps.second) {
206 auto volRep = detRep.
volumes.find(vid);
207 if (volRep == detRep.
volumes.end()) {
209 volRep = detRep.
volumes.find(vid);
210 volRep->second.volumeID = key;
212 volRep->second.material =
value.get();
215 return detectorRepToJson(detRep);
221 ACTS_VERBOSE(
"a2j: Writing json from detector representation");
229 volj[m_cfg.namekey] =
value.volumeName;
230 std::ostringstream svolumeID;
231 svolumeID <<
value.volumeID;
232 volj[m_cfg.geoidkey] = svolumeID.str();
233 if (
value.material) {
234 volj[m_cfg.matkey] = volumeMaterialToJson(*
value.material);
237 if (not
value.layers.empty()) {
240 for (
auto& [lkey, lvalue] :
value.layers) {
243 std::ostringstream slayerID;
244 slayerID << lvalue.layerID;
245 layj[m_cfg.geoidkey] = slayerID.str();
247 if (not lvalue.approaches.empty() and m_cfg.processApproaches) {
248 ACTS_VERBOSE(
"a2j: -----> Found " << lvalue.approaches.size()
249 <<
" approach surface(s)");
251 for (
auto& [akey, avalue] : lvalue.approaches) {
252 ACTS_VERBOSE(
"a2j: ------> Convert approach surface " << akey);
253 approachesj[
std::to_string(akey)] = surfaceMaterialToJson(*avalue);
254 if (lvalue.approacheSurfaces.find(akey) !=
255 lvalue.approacheSurfaces.end())
257 lvalue.approacheSurfaces.at(akey));
260 layj[m_cfg.appkey] = approachesj;
263 if (not lvalue.sensitives.empty() and m_cfg.processSensitives) {
264 ACTS_VERBOSE(
"a2j: -----> Found " << lvalue.sensitives.size()
265 <<
" sensitive surface(s)");
267 for (
auto& [skey, svalue] : lvalue.sensitives) {
268 ACTS_VERBOSE(
"a2j: ------> Convert sensitive surface " << skey);
269 sensitivesj[
std::to_string(skey)] = surfaceMaterialToJson(*svalue);
270 if (lvalue.sensitiveSurfaces.find(skey) !=
271 lvalue.sensitiveSurfaces.end())
273 lvalue.sensitiveSurfaces.at(skey));
276 layj[m_cfg.senkey] = sensitivesj;
279 if (lvalue.representing !=
nullptr and m_cfg.processRepresenting) {
280 ACTS_VERBOSE(
"a2j: ------> Convert representing surface ");
281 layj[m_cfg.repkey] = surfaceMaterialToJson(*lvalue.representing);
282 if (lvalue.representingSurface !=
nullptr)
283 addSurfaceToJson(layj[m_cfg.repkey], lvalue.representingSurface);
287 volj[m_cfg.laykey] = layersj;
290 if (not
value.boundaries.empty()) {
292 <<
" boundary/ies ");
294 for (
auto& [bkey, bvalue] :
value.boundaries) {
296 boundariesj[
std::to_string(bkey)] = surfaceMaterialToJson(*bvalue);
297 if (
value.boundarySurfaces.find(bkey) !=
value.boundarySurfaces.end())
299 value.boundarySurfaces.at(bkey));
301 volj[m_cfg.boukey] = boundariesj;
307 detectorj[m_cfg.volkey] = volumesj;
323 if (key == m_cfg.bin0key and not
value.empty()) {
324 bUtility += jsonToBinUtility(
value);
325 }
else if (key == m_cfg.bin1key and not
value.empty()) {
326 bUtility += jsonToBinUtility(
value);
328 if (key == m_cfg.datakey and not
value.empty()) {
329 mpMatrix = jsonToMaterialMatrix(
value);
334 if (mpMatrix.empty()) {
336 }
else if (bUtility.
bins() == 1) {
352 std::vector<std::vector<float>> mmat;
356 if (key == m_cfg.bin0key and not
value.empty()) {
357 bUtility += jsonToBinUtility(
value);
358 }
else if (key == m_cfg.bin1key and not
value.empty()) {
359 bUtility += jsonToBinUtility(
value);
360 }
else if (key == m_cfg.bin2key and not
value.empty()) {
361 bUtility += jsonToBinUtility(
value);
363 if (key == m_cfg.datakey and not
value.empty()) {
365 std::vector<float> mpVector{
bin[0],
bin[1], bin[2], bin[3], bin[4]};
366 mmat.push_back(mpVector);
374 }
else if (mmat.size() == 1) {
376 mmat[0][0], mmat[0][1], mmat[0][2], mmat[0][3], mmat[0][4]));
379 std::function<Acts::Vector2D(Acts::Vector3D)> transfoGlobalToLocal;
392 for (
size_t bin = 0;
bin < mmat.size();
bin++) {
394 mmat[bin][3], mmat[bin][4])
400 std::move(matMap), bUtility);
402 std::function<Acts::Vector3D(Acts::Vector3D)> transfoGlobalToLocal;
416 for (
size_t bin = 0;
bin < mmat.size();
bin++) {
418 mmat[bin][3], mmat[bin][4])
424 std::move(matMap), bUtility);
435 return detectorRepToJson(detRep);
448 for (
auto& vol : volumes) {
450 convertToRep(detRep, *vol);
458 convertToRep(detRep, *vol);
468 }
else if (m_cfg.processnonmaterial ==
true) {
478 for (
auto& lay : layers) {
479 auto layRep = convertToRep(*lay);
484 volRep.
layers.insert({lid, std::move(layRep)});
491 auto& bssfRep = bsurf->surfaceRepresentation();
492 if (bssfRep.surfaceMaterial() !=
nullptr) {
497 volRep.
boundaries[bid] = bssfRep.surfaceMaterial();
500 }
else if (m_cfg.processnonmaterial ==
true) {
516 detRep.
volumes.insert({vid, std::move(volRep)});
526 if (m_cfg.processSensitives and tLayer.
surfaceArray() !=
nullptr) {
528 if (ssf !=
nullptr && ssf->surfaceMaterial() !=
nullptr) {
531 layRep.
sensitives.insert({sid, ssf->surfaceMaterial()});
533 }
else if (m_cfg.processnonmaterial ==
true) {
551 }
else if (m_cfg.processnonmaterial ==
true) {
565 if (asf->surfaceMaterial() !=
nullptr) {
568 layRep.
approaches.insert({aid, asf->surfaceMaterial()});
570 }
else if (m_cfg.processnonmaterial ==
true) {
592 auto convertMaterialProperties =
598 mp.material().X0(), mp.material().L0(), mp.material().Ar(),
599 mp.material().Z(), mp.material().massDensity(), mp.thickness(),
609 if (psMaterial !=
nullptr) {
611 smj[m_cfg.typekey] =
"proto";
613 smj[m_cfg.mapkey] =
false;
614 bUtility = &(psMaterial->binUtility());
619 if (hsMaterial !=
nullptr) {
621 smj[m_cfg.typekey] =
"homogeneous";
622 smj[m_cfg.mapkey] =
true;
623 if (m_cfg.writeData) {
625 auto& mp = hsMaterial->materialProperties(0, 0);
626 std::vector<std::vector<std::vector<float>>> mmat = {
627 {convertMaterialProperties(mp)}};
628 smj[m_cfg.datakey] = mmat;
634 if (bsMaterial !=
nullptr) {
636 smj[m_cfg.typekey] =
"binned";
637 smj[m_cfg.mapkey] =
true;
638 bUtility = &(bsMaterial->binUtility());
641 if (m_cfg.writeData) {
642 auto& mpMatrix = bsMaterial->fullMaterial();
643 std::vector<std::vector<std::vector<float>>> mmat;
644 mmat.reserve(mpMatrix.size());
645 for (
auto& mpVector : mpMatrix) {
646 std::vector<std::vector<float>> mvec;
647 mvec.reserve(mpVector.size());
648 for (
auto& mp : mpVector) {
649 mvec.push_back(convertMaterialProperties(mp));
651 mmat.push_back(std::move(mvec));
653 smj[m_cfg.datakey] = mmat;
659 if (bUtility !=
nullptr) {
660 std::vector<std::string> binkeys = {m_cfg.bin0key, m_cfg.bin1key};
664 for (
size_t ibin = 0; ibin < binningData.size(); ++ibin) {
666 auto cbData = binningData[ibin];
676 if (smj[m_cfg.typekey] ==
"proto" && cbData.bins() > 1)
677 smj[m_cfg.mapkey] =
true;
679 if (smj[m_cfg.typekey] !=
"proto") {
680 std::pair<double, double> minMax = {cbData.min, cbData.max};
683 smj[binkeys[ibin]] = binj;
696 if (pvMaterial !=
nullptr) {
698 smj[m_cfg.typekey] =
"proto";
700 smj[m_cfg.mapkey] =
false;
701 bUtility = &(pvMaterial->binUtility());
706 if (hvMaterial !=
nullptr) {
708 smj[m_cfg.typekey] =
"homogeneous";
709 smj[m_cfg.mapkey] =
true;
710 if (m_cfg.writeData) {
712 auto mat = hvMaterial->material({0, 0, 0});
713 std::vector<std::vector<float>> mmat;
716 smj[m_cfg.datakey] = mmat;
720 auto bvMaterial2D =
dynamic_cast<
724 if (bvMaterial2D !=
nullptr) {
726 smj[m_cfg.typekey] =
"interpolated2D";
727 smj[m_cfg.mapkey] =
true;
728 bUtility = &(bvMaterial2D->binUtility());
730 if (m_cfg.writeData) {
731 std::vector<std::vector<float>> mmat;
739 mmat.push_back({0, 0, 0, 0, 0});
742 smj[m_cfg.datakey] = mmat;
749 if (bvMaterial3D !=
nullptr) {
751 smj[m_cfg.typekey] =
"interpolated3D";
752 smj[m_cfg.mapkey] =
true;
753 bUtility = &(bvMaterial3D->binUtility());
755 if (m_cfg.writeData) {
756 std::vector<std::vector<float>> mmat;
764 mmat.push_back({0, 0, 0, 0, 0});
767 smj[m_cfg.datakey] = mmat;
774 if (bUtility !=
nullptr) {
775 std::vector<std::string> binkeys = {m_cfg.bin0key, m_cfg.bin1key,
780 for (
size_t ibin = 0; ibin < binningData.size(); ++ibin) {
782 auto cbData = binningData[ibin];
792 if (smj[m_cfg.typekey] ==
"proto" && cbData.bins() > 1)
793 smj[m_cfg.mapkey] =
true;
795 if (smj[m_cfg.typekey] !=
"proto") {
796 std::pair<double, double> minMax = {cbData.min, cbData.max};
799 smj[binkeys[ibin]] = binj;
808 std::ostringstream SurfaceID;
809 SurfaceID << surface->
geoID();
810 sjson[m_cfg.surfacegeoidkey] = SurfaceID.str();
823 if (radialBounds !=
nullptr) {
824 sjson[m_cfg.surfacetypekey] =
"Disk";
825 sjson[m_cfg.surfacepositionkey] = sTransform.translation().z();
826 sjson[m_cfg.surfacerangekey] = {radialBounds->
rMin(), radialBounds->
rMax()};
828 if (cylinderBounds !=
nullptr) {
829 sjson[m_cfg.surfacetypekey] =
"Cylinder";
831 sjson[m_cfg.surfacerangekey] = {
835 if (annulusBounds !=
nullptr) {
836 sjson[m_cfg.surfacetypekey] =
"Annulus";
837 sjson[m_cfg.surfacepositionkey] = sTransform.translation().z();
838 sjson[m_cfg.surfacerangekey] = {
839 {annulusBounds->
rMin(), annulusBounds->
rMax()},
849 for (
auto& outer : data) {
851 for (
auto& inner : outer) {
852 if (inner.size() > 5) {
854 inner[0], inner[1], inner[2], inner[3], inner[4], inner[5]));
859 mpMatrix.push_back(std::move(mpVector));
873 unsigned int bins = bin[2];
876 if (bin[3].size() == 2) {
895 if (radialBounds !=
nullptr) {
905 if (cylinderBounds !=
nullptr) {
918 if (annulusBounds !=
nullptr) {
937 if (cyBounds !=
nullptr) {
949 }
else if (cuBounds !=
nullptr) {