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());