File indexing completed on 2025-08-05 08:10:14
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Plugins/ActSVG/SurfaceArraySvgConverter.hpp"
0010
0011 #include "Acts/Plugins/ActSVG/SurfaceSvgConverter.hpp"
0012 #include "Acts/Surfaces/Surface.hpp"
0013 #include "Acts/Surfaces/SurfaceArray.hpp"
0014 #include "Acts/Surfaces/SurfaceBounds.hpp"
0015
0016 std::tuple<std::vector<Acts::Svg::ProtoSurfaces>, Acts::Svg::ProtoGrid,
0017 std::vector<Acts::Svg::ProtoAssociations> >
0018 Acts::Svg::SurfaceArrayConverter::convert(
0019 const GeometryContext& gctx, const SurfaceArray& surfaceArray,
0020 const SurfaceArrayConverter::Options& cOptions) {
0021
0022 ProtoSurfaces pSurfaces;
0023 ProtoGrid pGrid;
0024 ProtoAssociations pAssociations;
0025
0026 const auto& surfaces = surfaceArray.surfaces();
0027
0028
0029 auto binning = surfaceArray.binningValues();
0030 auto axes = surfaceArray.getAxes();
0031
0032 enum ViewType { cylinder, polar, planar, none };
0033 ViewType vType = none;
0034
0035 if (!binning.empty() && binning.size() == 2 && axes.size() == 2) {
0036
0037 std::vector<Acts::ActsScalar> edges0;
0038 std::vector<Acts::ActsScalar> edges1;
0039
0040 auto convertGridEdges = [](const std::vector<Acts::ActsScalar>& actsEdges)
0041 -> std::vector<actsvg::scalar> {
0042 std::vector<actsvg::scalar> svgEdges;
0043 svgEdges.reserve(actsEdges.size());
0044 for (const auto ae : actsEdges) {
0045 svgEdges.push_back(static_cast<actsvg::scalar>(ae));
0046 }
0047 return svgEdges;
0048 };
0049
0050
0051 if (binning[0] == binPhi && binning[1] == binZ) {
0052 vType = cylinder;
0053
0054 edges1 = axes[0]->getBinEdges();
0055 edges0 = axes[1]->getBinEdges();
0056 pGrid._type = actsvg::proto::grid::e_z_phi;
0057 } else if (binning[0] == binPhi && binning[1] == binR) {
0058 vType = polar;
0059
0060 edges1 = axes[0]->getBinEdges();
0061 edges0 = axes[1]->getBinEdges();
0062 pGrid._type = actsvg::proto::grid::e_r_phi;
0063 } else if (binning[0] == binZ && binning[1] == binPhi) {
0064
0065 vType = cylinder;
0066 edges0 = axes[0]->getBinEdges();
0067 edges1 = axes[1]->getBinEdges();
0068 pGrid._type = actsvg::proto::grid::e_z_phi;
0069 } else if (binning[0] == binR && binning[1] == binPhi) {
0070
0071 vType = polar;
0072 edges0 = axes[0]->getBinEdges();
0073 edges1 = axes[1]->getBinEdges();
0074 pGrid._type = actsvg::proto::grid::e_r_phi;
0075 }
0076
0077 pGrid._edges_0 = convertGridEdges(edges0);
0078 pGrid._edges_1 = convertGridEdges(edges1);
0079 }
0080
0081
0082 std::vector<actsvg::svg::object> templateObjects;
0083 std::vector<const SurfaceBounds*> templateBounds;
0084
0085 for (const auto& sf : surfaces) {
0086
0087 const SurfaceBounds& sBounds = sf->bounds();
0088
0089 auto sameBounds = [&](const SurfaceBounds* test) {
0090 return ((*test) == sBounds);
0091 };
0092
0093 auto tBounds =
0094 std::find_if(templateBounds.begin(), templateBounds.end(), sameBounds);
0095
0096 if (tBounds == templateBounds.end()) {
0097
0098 SurfaceConverter::Options sOptions;
0099 sOptions.templateSurface = true;
0100
0101 auto sfStyle = cOptions.surfaceStyles.find(sf->geometryId());
0102 if (sfStyle != cOptions.surfaceStyles.end()) {
0103 sOptions.style = *sfStyle;
0104 }
0105
0106
0107 auto referenceSurface = SurfaceConverter::convert(gctx, *sf, sOptions);
0108 auto referenceObject =
0109 View::xy(referenceSurface,
0110 "Template_" + std::to_string(templateObjects.size()));
0111 templateBounds.push_back(&sBounds);
0112 templateObjects.push_back(referenceObject);
0113 }
0114 }
0115
0116
0117 ActsScalar radius = 0.;
0118
0119
0120 for (const auto& sf : surfaces) {
0121 radius += Acts::VectorHelpers::perp(sf->center(gctx));
0122
0123
0124 SurfaceConverter::Options sOptions;
0125 sOptions.templateSurface = vType != cylinder;
0126
0127 auto sfStyle = cOptions.surfaceStyles.find(sf->geometryId());
0128 if (sfStyle != cOptions.surfaceStyles.end()) {
0129 sOptions.style = *sfStyle;
0130 }
0131
0132
0133 auto cSurface = Acts::Svg::SurfaceConverter::convert(gctx, *sf, sOptions);
0134 cSurface._name = "Module_n_" + std::to_string(pSurfaces.size());
0135
0136 cSurface._aux_info["grid_info"] = {
0137 "* module " + std::to_string(pSurfaces.size()) +
0138 ", surface = " + std::to_string(sf->geometryId().sensitive())};
0139
0140 if (vType == cylinder) {
0141 const SurfaceBounds& sBounds = sf->bounds();
0142
0143 auto sameBounds = [&](const SurfaceBounds* test) {
0144 return ((*test) == sBounds);
0145 };
0146
0147 auto tBounds = std::find_if(templateBounds.begin(), templateBounds.end(),
0148 sameBounds);
0149
0150 if (tBounds != templateBounds.end()) {
0151 std::size_t tObject = std::distance(templateBounds.begin(), tBounds);
0152 cSurface._template_object = templateObjects[tObject];
0153 }
0154 }
0155
0156 if (vType == planar || vType == polar) {
0157
0158
0159 const auto& sTransform = sf->transform(gctx);
0160 Vector3 localA = sTransform.rotation().col(0);
0161 Vector3 localZ = sTransform.rotation().col(2);
0162
0163 ActsScalar projZ = localZ.dot(Vector3(0., 0., 1.));
0164 ActsScalar alpha = std::atan2(localA[1], localA[0]) / M_PI * 180.;
0165 if (projZ < 0.) {
0166 alpha += 180.;
0167 }
0168 auto surfaceCenter = sf->center(gctx);
0169
0170 cSurface._transform._tr = {static_cast<actsvg::scalar>(surfaceCenter[0]),
0171 static_cast<actsvg::scalar>(surfaceCenter[1])};
0172 cSurface._transform._rot = {static_cast<actsvg::scalar>(alpha), 0., 0.};
0173 }
0174
0175 pSurfaces.push_back(cSurface);
0176 }
0177 radius /= surfaces.size();
0178
0179
0180 for (unsigned int il0 = 1; il0 < pGrid._edges_0.size(); ++il0) {
0181 ActsScalar p0 = 0.5 * (pGrid._edges_0[il0] + pGrid._edges_0[il0 - 1]);
0182 for (unsigned int il1 = 1; il1 < pGrid._edges_1.size(); ++il1) {
0183 ActsScalar p1 = 0.5 * (pGrid._edges_1[il1] + pGrid._edges_1[il1 - 1]);
0184
0185 Vector3 bCenter;
0186 if (vType == polar) {
0187 bCenter = Vector3(p0 * std::cos(p1), p0 * std::sin(p1), 0.);
0188 } else if (vType == cylinder) {
0189 bCenter = Vector3(radius * std::cos(p1), radius * std::sin(p1), p0);
0190 }
0191
0192 auto bSurfaces = surfaceArray.neighbors(bCenter);
0193 std::vector<std::size_t> binnAssoc;
0194 for (const auto& bs : bSurfaces) {
0195 auto candidate = std::find(surfaces.begin(), surfaces.end(), bs);
0196 if (candidate != surfaces.end()) {
0197 binnAssoc.push_back(std::distance(surfaces.begin(), candidate));
0198 }
0199 }
0200 pAssociations.push_back(binnAssoc);
0201 }
0202 }
0203
0204 std::vector<ProtoSurfaces> pSurfaceBatches = {pSurfaces};
0205 std::vector<ProtoAssociations> pAssociationBatchs = {pAssociations};
0206 return std::tie(pSurfaceBatches, pGrid, pAssociationBatchs);
0207 }