Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-29 08:24:12

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/GeometryContext.hpp"
0013 #include "Acts/Geometry/GeometryIdentifier.hpp"
0014 #include "Acts/Surfaces/ConeBounds.hpp"
0015 #include "Acts/Surfaces/ConeSurface.hpp"
0016 #include "Acts/Surfaces/ConvexPolygonBounds.hpp"
0017 #include "Acts/Surfaces/CylinderBounds.hpp"
0018 #include "Acts/Surfaces/CylinderSurface.hpp"
0019 #include "Acts/Surfaces/DiamondBounds.hpp"
0020 #include "Acts/Surfaces/DiscSurface.hpp"
0021 #include "Acts/Surfaces/LineBounds.hpp"
0022 #include "Acts/Surfaces/PerigeeSurface.hpp"
0023 #include "Acts/Surfaces/PlaneSurface.hpp"
0024 #include "Acts/Surfaces/PointBounds.hpp"
0025 #include "Acts/Surfaces/PointSurface.hpp"
0026 #include "Acts/Surfaces/RadialBounds.hpp"
0027 #include "Acts/Surfaces/RectangleBounds.hpp"
0028 #include "Acts/Surfaces/StrawSurface.hpp"
0029 #include "Acts/Surfaces/Surface.hpp"
0030 #include "Acts/Surfaces/SurfaceBounds.hpp"
0031 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0032 #include "ActsPlugins/Json/SurfaceJsonConverter.hpp"
0033 
0034 #include <array>
0035 #include <fstream>
0036 #include <memory>
0037 #include <stdexcept>
0038 #include <string>
0039 
0040 #include <nlohmann/json.hpp>
0041 
0042 using namespace Acts;
0043 
0044 namespace {
0045 std::ofstream out;
0046 
0047 auto gctx = GeometryContext::dangerouslyDefaultConstruct();
0048 }  // namespace
0049 
0050 namespace ActsTests {
0051 
0052 BOOST_AUTO_TEST_SUITE(JsonSuite)
0053 
0054 BOOST_AUTO_TEST_CASE(ConeSurfaceRoundTripTests) {
0055   Transform3 trf(Transform3::Identity() * Translation3(0., 0., -7.));
0056   auto cone = std::make_shared<ConeBounds>(0.123, 10., 100.);
0057   auto coneRef = Surface::makeShared<ConeSurface>(trf, cone);
0058   coneRef->assignGeometryId(GeometryIdentifier(13u));
0059 
0060   // Test a cone
0061   nlohmann::json coneOut = SurfaceJsonConverter::toJson(gctx, *coneRef);
0062   out.open("ConeSurface.json");
0063   out << coneOut.dump(2);
0064   out.close();
0065 
0066   auto in = std::ifstream("ConeSurface.json",
0067                           std::ifstream::in | std::ifstream::binary);
0068   BOOST_CHECK(in.good());
0069   nlohmann::json coneIn;
0070   in >> coneIn;
0071   in.close();
0072 
0073   auto coneTest = SurfaceJsonConverter::fromJson(coneIn);
0074 
0075   BOOST_CHECK(coneTest->localToGlobalTransform(gctx).isApprox(
0076       coneRef->localToGlobalTransform(gctx)));
0077   BOOST_CHECK_EQUAL(coneTest->geometryId(), coneRef->geometryId());
0078   BOOST_CHECK_EQUAL(coneTest->bounds(), coneRef->bounds());
0079 }
0080 
0081 BOOST_AUTO_TEST_CASE(DiscSurfaceRoundTripTests) {
0082   Transform3 trf(Transform3::Identity() * Translation3(0., 0., -7.));
0083   auto ring = std::make_shared<RadialBounds>(0., 4.);
0084   auto ringDiscRef = Surface::makeShared<DiscSurface>(trf, ring);
0085   ringDiscRef->assignGeometryId(GeometryIdentifier(10u));
0086 
0087   // Test a disc
0088   nlohmann::json discOut = SurfaceJsonConverter::toJson(gctx, *ringDiscRef);
0089   out.open("DiscSurface.json");
0090   out << discOut.dump(2);
0091   out.close();
0092 
0093   auto in = std::ifstream("DiscSurface.json",
0094                           std::ifstream::in | std::ifstream::binary);
0095   BOOST_CHECK(in.good());
0096   nlohmann::json discIn;
0097   in >> discIn;
0098   in.close();
0099 
0100   auto ringDiscTest = SurfaceJsonConverter::fromJson(discIn);
0101 
0102   BOOST_CHECK(ringDiscTest->localToGlobalTransform(gctx).isApprox(
0103       ringDiscRef->localToGlobalTransform(gctx)));
0104   BOOST_CHECK_EQUAL(ringDiscTest->geometryId(), ringDiscRef->geometryId());
0105   BOOST_CHECK_EQUAL(ringDiscTest->bounds(), ringDiscRef->bounds());
0106 }
0107 
0108 BOOST_AUTO_TEST_CASE(CylinderSurfaceRoundTripTests) {
0109   Transform3 trf(Transform3::Identity() * Translation3(0., 0., -7.));
0110   auto tube = std::make_shared<CylinderBounds>(5., 20.);
0111   auto cylinderRef = Surface::makeShared<CylinderSurface>(trf, tube);
0112   cylinderRef->assignGeometryId(GeometryIdentifier(11u));
0113 
0114   // Test a cyoinder
0115   nlohmann::json cylinderOut = SurfaceJsonConverter::toJson(gctx, *cylinderRef);
0116   out.open("CylinderSurface.json");
0117   out << cylinderOut.dump(2);
0118   out.close();
0119 
0120   auto in = std::ifstream("CylinderSurface.json",
0121                           std::ifstream::in | std::ifstream::binary);
0122   BOOST_CHECK(in.good());
0123   nlohmann::json cylinderIn;
0124   in >> cylinderIn;
0125   in.close();
0126 
0127   auto cylinderTest = SurfaceJsonConverter::fromJson(cylinderIn);
0128 
0129   BOOST_CHECK(cylinderTest->localToGlobalTransform(gctx).isApprox(
0130       cylinderRef->localToGlobalTransform(gctx)));
0131   BOOST_CHECK_EQUAL(cylinderTest->geometryId(), cylinderRef->geometryId());
0132   BOOST_CHECK_EQUAL(cylinderTest->bounds(), cylinderRef->bounds());
0133 }
0134 
0135 BOOST_AUTO_TEST_CASE(PlaneSurfaceRoundTripTests) {
0136   Transform3 trf(Transform3::Identity() * Translation3(0., 0., -7.));
0137   auto trapezoid = std::make_shared<TrapezoidBounds>(2., 3., 4.);
0138   auto trapezoidPlaneRef = Surface::makeShared<PlaneSurface>(trf, trapezoid);
0139   trapezoidPlaneRef->assignGeometryId(GeometryIdentifier(9u));
0140 
0141   // Test a plane
0142   nlohmann::json planeOut =
0143       SurfaceJsonConverter::toJson(gctx, *trapezoidPlaneRef);
0144   to_json(planeOut, *trapezoidPlaneRef);
0145   out.open("PlaneSurface.json");
0146   out << planeOut.dump(2);
0147   out.close();
0148 
0149   auto in = std::ifstream("PlaneSurface.json",
0150                           std::ifstream::in | std::ifstream::binary);
0151   BOOST_CHECK(in.good());
0152   nlohmann::json planeIn;
0153   in >> planeIn;
0154   in.close();
0155 
0156   auto trapezoidPlaneTest = SurfaceJsonConverter::fromJson(planeIn);
0157 
0158   BOOST_CHECK(trapezoidPlaneTest->localToGlobalTransform(gctx).isApprox(
0159       trapezoidPlaneRef->localToGlobalTransform(gctx)));
0160   BOOST_CHECK_EQUAL(trapezoidPlaneTest->geometryId(),
0161                     trapezoidPlaneRef->geometryId());
0162   BOOST_CHECK_EQUAL(trapezoidPlaneTest->bounds(), trapezoidPlaneRef->bounds());
0163 }
0164 
0165 BOOST_AUTO_TEST_CASE(StrawSurfaceRoundTripTests) {
0166   Transform3 trf(Transform3::Identity() * Translation3(0., 0., -7.));
0167   auto straw = std::make_shared<LineBounds>(1., 100.);
0168   auto strawRef = Surface::makeShared<StrawSurface>(trf, straw);
0169   strawRef->assignGeometryId(GeometryIdentifier(12u));
0170 
0171   // Test a straw
0172   nlohmann::json strawOut = SurfaceJsonConverter::toJson(gctx, *strawRef);
0173   out.open("StrawSurface.json");
0174   out << strawOut.dump(2);
0175   out.close();
0176 
0177   auto in = std::ifstream("StrawSurface.json",
0178                           std::ifstream::in | std::ifstream::binary);
0179   BOOST_CHECK(in.good());
0180   nlohmann::json strawIn;
0181   in >> strawIn;
0182   in.close();
0183 
0184   auto strawTest = SurfaceJsonConverter::fromJson(strawIn);
0185 
0186   BOOST_CHECK(strawTest->localToGlobalTransform(gctx).isApprox(
0187       strawRef->localToGlobalTransform(gctx)));
0188   BOOST_CHECK_EQUAL(strawTest->geometryId(), strawRef->geometryId());
0189   BOOST_CHECK_EQUAL(strawTest->bounds(), strawRef->bounds());
0190 }
0191 
0192 BOOST_AUTO_TEST_CASE(PerigeeRoundTripTests) {
0193   Transform3 trf(Transform3::Identity() * Translation3(-1., -2., -7.));
0194   auto perigeeRef = Surface::makeShared<PerigeeSurface>(trf);
0195   perigeeRef->assignGeometryId(GeometryIdentifier(99u));
0196 
0197   // Test a perigee
0198   nlohmann::json perigeeOut = SurfaceJsonConverter::toJson(gctx, *perigeeRef);
0199   out.open("PerigeeSurface.json");
0200   out << perigeeOut.dump(2);
0201   out.close();
0202 
0203   auto in = std::ifstream("PerigeeSurface.json",
0204                           std::ifstream::in | std::ifstream::binary);
0205   BOOST_CHECK(in.good());
0206   nlohmann::json perigeeIn;
0207   in >> perigeeIn;
0208   in.close();
0209 
0210   auto perigeeTest = SurfaceJsonConverter::fromJson(perigeeIn);
0211 
0212   BOOST_CHECK(perigeeTest->localToGlobalTransform(gctx).isApprox(
0213       perigeeRef->localToGlobalTransform(gctx)));
0214   BOOST_CHECK_EQUAL(perigeeTest->geometryId(), perigeeRef->geometryId());
0215 }
0216 
0217 BOOST_AUTO_TEST_CASE(PointSurfaceRoundTripTests) {
0218   Transform3 trf(Transform3::Identity() * Translation3(1., -2., 3.));
0219 
0220   // unbounded point surface
0221   auto pointRef = Surface::makeShared<PointSurface>(trf);
0222   pointRef->assignGeometryId(GeometryIdentifier(77u));
0223 
0224   nlohmann::json pointOut = SurfaceJsonConverter::toJson(gctx, *pointRef);
0225   out.open("PointSurface.json");
0226   out << pointOut.dump(2);
0227   out.close();
0228 
0229   auto in = std::ifstream("PointSurface.json",
0230                           std::ifstream::in | std::ifstream::binary);
0231   BOOST_CHECK(in.good());
0232   nlohmann::json jPointIn;
0233   in >> jPointIn;
0234   in.close();
0235 
0236   auto pointTest = SurfaceJsonConverter::fromJson(jPointIn);
0237   BOOST_CHECK_EQUAL(pointTest->type(), Surface::Point);
0238   BOOST_CHECK(pointTest->localToGlobalTransform(gctx).isApprox(
0239       pointRef->localToGlobalTransform(gctx)));
0240   BOOST_CHECK_EQUAL(pointTest->geometryId(), pointRef->geometryId());
0241 
0242   // bounded point surface (max distance)
0243   auto pbounds = std::make_shared<PointBounds>(5.);
0244   auto boundedRef = Surface::makeShared<PointSurface>(trf, pbounds);
0245   boundedRef->assignGeometryId(GeometryIdentifier(78u));
0246 
0247   nlohmann::json boundedOut = SurfaceJsonConverter::toJson(gctx, *boundedRef);
0248   out.open("PointSurfaceBounded.json");
0249   out << boundedOut.dump(2);
0250   out.close();
0251 
0252   auto bins = std::ifstream("PointSurfaceBounded.json",
0253                             std::ifstream::in | std::ifstream::binary);
0254   BOOST_CHECK(bins.good());
0255   nlohmann::json jBoundedIn;
0256   bins >> jBoundedIn;
0257   bins.close();
0258 
0259   auto boundedTest = SurfaceJsonConverter::fromJson(jBoundedIn);
0260   BOOST_CHECK_EQUAL(boundedTest->type(), Surface::Point);
0261   BOOST_CHECK_EQUAL(boundedTest->bounds(), boundedRef->bounds());
0262 }
0263 
0264 BOOST_AUTO_TEST_CASE(DiamondPlaneSurfaceRoundTripTests) {
0265   Transform3 trf(Transform3::Identity() * Translation3(0., 0., -7.));
0266   auto diamond = std::make_shared<DiamondBounds>(1., 3., 2., 4., 5.);
0267   auto diamondPlaneRef = Surface::makeShared<PlaneSurface>(trf, diamond);
0268   diamondPlaneRef->assignGeometryId(GeometryIdentifier(14u));
0269 
0270   nlohmann::json planeOut =
0271       SurfaceJsonConverter::toJson(gctx, *diamondPlaneRef);
0272   out.open("DiamondPlaneSurface.json");
0273   out << planeOut.dump(2);
0274   out.close();
0275 
0276   auto in = std::ifstream("DiamondPlaneSurface.json",
0277                           std::ifstream::in | std::ifstream::binary);
0278   BOOST_CHECK(in.good());
0279   nlohmann::json planeIn;
0280   in >> planeIn;
0281   in.close();
0282 
0283   auto diamondPlaneTest = SurfaceJsonConverter::fromJson(planeIn);
0284 
0285   BOOST_CHECK(diamondPlaneTest->localToGlobalTransform(gctx).isApprox(
0286       diamondPlaneRef->localToGlobalTransform(gctx)));
0287   BOOST_CHECK_EQUAL(diamondPlaneTest->geometryId(),
0288                     diamondPlaneRef->geometryId());
0289   BOOST_CHECK_EQUAL(diamondPlaneTest->bounds(), diamondPlaneRef->bounds());
0290 }
0291 
0292 BOOST_AUTO_TEST_CASE(SurfaceBoundsDecouplingTests) {
0293   Transform3 trf(Transform3::Identity());
0294   auto planeRef = Surface::makeShared<PlaneSurface>(
0295       trf, std::make_shared<RectangleBounds>(4., 6.));
0296 
0297   nlohmann::json jPlane = SurfaceJsonConverter::toJson(gctx, *planeRef);
0298 
0299   // Surface and bounds each carry their own discriminator, so neither needs
0300   // the concatenated "kind" the decoder used to be keyed on
0301   BOOST_CHECK(!jPlane.contains("kind"));
0302   BOOST_CHECK(!jPlane["bounds"].contains("kind"));
0303   BOOST_CHECK_EQUAL(jPlane["type"], "PlaneSurface");
0304   BOOST_CHECK_EQUAL(jPlane["bounds"]["type"], "RectangleBounds");
0305 
0306   // ConvexPolygonBounds<N> resolves through the single ConvexPolygonBounds
0307   // bounds decoder, whatever N was written
0308   std::array<Vector2, 4> vertices{Vector2(-1., -1.), Vector2(1., -1.),
0309                                   Vector2(1., 1.), Vector2(-1., 1.)};
0310   auto polyRef = Surface::makeShared<PlaneSurface>(
0311       trf, std::make_shared<ConvexPolygonBounds<4>>(vertices));
0312   auto polyTest = SurfaceJsonConverter::fromJson(
0313       SurfaceJsonConverter::toJson(gctx, *polyRef));
0314   BOOST_CHECK_EQUAL(polyTest->bounds().type(), SurfaceBounds::eConvexPolygon);
0315   BOOST_CHECK(polyTest->bounds().values() == polyRef->bounds().values());
0316 
0317   // A surface paired with bounds it cannot store is a decode-time error
0318   nlohmann::json jMismatch = jPlane;
0319   jMismatch["type"] = "CylinderSurface";
0320   BOOST_CHECK_THROW(SurfaceJsonConverter::fromJson(jMismatch),
0321                     std::invalid_argument);
0322 }
0323 
0324 BOOST_AUTO_TEST_SUITE_END()
0325 
0326 }  // namespace ActsTests