Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:25:35

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/Utilities/GridAccessHelpers.hpp"
0012 #include "Acts/Utilities/GridAxisGenerators.hpp"
0013 #include "ActsPlugins/Json/GridJsonConverter.hpp"
0014 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0015 
0016 #include <array>
0017 #include <fstream>
0018 #include <memory>
0019 #include <numbers>
0020 #include <vector>
0021 
0022 #include <nlohmann/json.hpp>
0023 
0024 using namespace Acts;
0025 
0026 namespace ActsTests {
0027 
0028 BOOST_AUTO_TEST_SUITE(JsonSuite)
0029 
0030 BOOST_AUTO_TEST_CASE(Grid1DSingleEntry) {
0031   // Bound equidistant
0032   using EqBound = GridAxisGenerators::EqBound;
0033 
0034   EqBound eqBound{{0., 5.}, 5};
0035   // Create the grid with the provided axis generator
0036   using GridTypeEQB = typename EqBound::template grid_type<std::size_t>;
0037   GridTypeEQB eqBoundGrid(eqBound());
0038 
0039   eqBoundGrid.at(1u) = 1u;
0040   eqBoundGrid.at(2u) = 2u;
0041   eqBoundGrid.at(3u) = 3u;
0042   eqBoundGrid.at(4u) = 4u;
0043   eqBoundGrid.at(5u) = 5u;
0044 
0045   auto p1 = typename GridTypeEQB::point_t{0.5};
0046   BOOST_CHECK_EQUAL(eqBoundGrid.atPosition(p1), 1u);
0047   auto p2 = typename GridTypeEQB::point_t{1.5};
0048   BOOST_CHECK_EQUAL(eqBoundGrid.atPosition(p2), 2u);
0049   auto p3 = typename GridTypeEQB::point_t{2.5};
0050   BOOST_CHECK_EQUAL(eqBoundGrid.atPosition(p3), 3u);
0051   auto p4 = typename GridTypeEQB::point_t{3.5};
0052   BOOST_CHECK_EQUAL(eqBoundGrid.atPosition(p4), 4u);
0053   auto p5 = typename GridTypeEQB::point_t{4.5};
0054   BOOST_CHECK_EQUAL(eqBoundGrid.atPosition(p5), 5u);
0055 
0056   nlohmann::json eqBoundJson = GridJsonConverter::toJson(eqBoundGrid);
0057 
0058   auto eqBoundGridRead =
0059       GridJsonConverter::fromJson<EqBound, std::size_t>(eqBoundJson, eqBound);
0060 
0061   BOOST_CHECK_EQUAL(eqBoundGridRead.at(1u), 1u);
0062   BOOST_CHECK_EQUAL(eqBoundGridRead.at(2u), 2u);
0063   BOOST_CHECK_EQUAL(eqBoundGridRead.at(3u), 3u);
0064   BOOST_CHECK_EQUAL(eqBoundGridRead.at(4u), 4u);
0065   BOOST_CHECK_EQUAL(eqBoundGridRead.at(5u), 5u);
0066 
0067   // Bound variable
0068   using VarBound = GridAxisGenerators::VarBound;
0069 
0070   VarBound varBound{{10., 11., 22., 333., 4444., 55555.}};
0071   // Create the grid with the provided axis generator
0072   using GridTypeEQV = typename VarBound::template grid_type<std::size_t>;
0073   GridTypeEQV varBoundGrid(varBound());
0074 
0075   varBoundGrid.at(1u) = 1u;
0076   varBoundGrid.at(2u) = 2u;
0077   varBoundGrid.at(3u) = 3u;
0078   varBoundGrid.at(4u) = 4u;
0079   varBoundGrid.at(5u) = 5u;
0080 
0081   nlohmann::json varBoundJson = GridJsonConverter::toJson(varBoundGrid);
0082 
0083   auto varBoundGridRead = GridJsonConverter::fromJson<VarBound, std::size_t>(
0084       varBoundJson, varBound);
0085 
0086   BOOST_CHECK_EQUAL(varBoundGridRead.at(1u), 1u);
0087   BOOST_CHECK_EQUAL(varBoundGridRead.at(2u), 2u);
0088   BOOST_CHECK_EQUAL(varBoundGridRead.at(3u), 3u);
0089   BOOST_CHECK_EQUAL(varBoundGridRead.at(4u), 4u);
0090   BOOST_CHECK_EQUAL(varBoundGridRead.at(5u), 5u);
0091 
0092   // Closed equidistant
0093   using EqClosed = GridAxisGenerators::EqClosed;
0094 
0095   EqClosed eqClosed{{0., 5.}, 5};
0096   // Create the grid with the provided axis generator
0097   using GridTypeEQC = typename EqClosed::template grid_type<std::size_t>;
0098   GridTypeEQC eqClosedGrid(eqClosed());
0099 
0100   eqClosedGrid.at(1u) = 1u;
0101   eqClosedGrid.at(2u) = 2u;
0102   eqClosedGrid.at(3u) = 3u;
0103   eqClosedGrid.at(4u) = 4u;
0104   eqClosedGrid.at(5u) = 5u;
0105 
0106   nlohmann::json eqClosedJson = GridJsonConverter::toJson(eqClosedGrid);
0107 
0108   auto eqClosedGridRead = GridJsonConverter::fromJson<EqClosed, std::size_t>(
0109       eqClosedJson, eqClosed);
0110 
0111   BOOST_CHECK_EQUAL(eqClosedGridRead.at(1u), 1u);
0112   BOOST_CHECK_EQUAL(eqClosedGridRead.at(2u), 2u);
0113   BOOST_CHECK_EQUAL(eqClosedGridRead.at(3u), 3u);
0114   BOOST_CHECK_EQUAL(eqClosedGridRead.at(4u), 4u);
0115   BOOST_CHECK_EQUAL(eqClosedGridRead.at(5u), 5u);
0116 }
0117 
0118 BOOST_AUTO_TEST_CASE(Grid1DArrayEntry) {
0119   // Bound equidistant
0120   using EqBound = GridAxisGenerators::EqBound;
0121 
0122   EqBound eqBound{{0., 5.}, 5};
0123   // Create the grid with the provided axis generator
0124   using GridTypeEQB =
0125       typename EqBound::template grid_type<std::array<std::size_t, 2u>>;
0126   GridTypeEQB eqBoundGrid(eqBound());
0127 
0128   eqBoundGrid.at(1u) = {1u, 1u};
0129   eqBoundGrid.at(2u) = {2u, 2u};
0130   eqBoundGrid.at(3u) = {3u, 3u};
0131   eqBoundGrid.at(4u) = {4u, 4u};
0132   eqBoundGrid.at(5u) = {5u, 5u};
0133 
0134   nlohmann::json eqBoundJson = GridJsonConverter::toJson(eqBoundGrid);
0135 
0136   auto eqBoundGridRead =
0137       GridJsonConverter::fromJson<EqBound, std::array<std::size_t, 2u>>(
0138           eqBoundJson, eqBound);
0139 
0140   BOOST_CHECK((eqBoundGridRead.at(1u) == std::array<std::size_t, 2u>{1u, 1u}));
0141   BOOST_CHECK((eqBoundGridRead.at(2u) == std::array<std::size_t, 2u>{2u, 2u}));
0142   BOOST_CHECK((eqBoundGridRead.at(3u) == std::array<std::size_t, 2u>{3u, 3u}));
0143   BOOST_CHECK((eqBoundGridRead.at(4u) == std::array<std::size_t, 2u>{4u, 4u}));
0144   BOOST_CHECK((eqBoundGridRead.at(5u) == std::array<std::size_t, 2u>{5u, 5u}));
0145 }
0146 
0147 BOOST_AUTO_TEST_CASE(Grid2DSingleEntryBound) {
0148   using EqBoundEqBound = GridAxisGenerators::EqBoundEqBound;
0149 
0150   EqBoundEqBound eqBound2{{0., 5.}, 5, {0., 2.}, 2};
0151   // Create the grid with the provided axis generator
0152   using GridTypeEQB2 = typename EqBoundEqBound::template grid_type<std::size_t>;
0153   GridTypeEQB2 eqBound2Grid(eqBound2());
0154 
0155   // Let's write in local coordinates
0156   using GridPoint = typename GridTypeEQB2::point_t;
0157 
0158   // First row access
0159   GridPoint p11{0.5, 0.5};
0160   GridPoint p12{1.5, 0.5};
0161   GridPoint p13{2.5, 0.5};
0162   GridPoint p14{3.5, 0.5};
0163   GridPoint p15{4.5, 0.5};
0164   eqBound2Grid.atPosition(p11) = 11u;
0165   eqBound2Grid.atPosition(p12) = 12u;
0166   eqBound2Grid.atPosition(p13) = 13u;
0167   eqBound2Grid.atPosition(p14) = 14u;
0168   eqBound2Grid.atPosition(p15) = 15u;
0169 
0170   // Second row access
0171   GridPoint p21{0.5, 1.5};
0172   GridPoint p22{1.5, 1.5};
0173   GridPoint p23{2.5, 1.5};
0174   GridPoint p24{3.5, 1.5};
0175   GridPoint p25{4.5, 1.5};
0176   eqBound2Grid.atPosition(p21) = 21u;
0177   eqBound2Grid.atPosition(p22) = 22u;
0178   eqBound2Grid.atPosition(p23) = 23u;
0179   eqBound2Grid.atPosition(p24) = 24u;
0180   eqBound2Grid.atPosition(p25) = 25u;
0181 
0182   nlohmann::json eqBound2Json = GridJsonConverter::toJson(eqBound2Grid);
0183 
0184   auto eqBound2JsonRead =
0185       GridJsonConverter::fromJson<EqBoundEqBound, std::size_t>(eqBound2Json,
0186                                                                eqBound2);
0187 
0188   BOOST_CHECK_EQUAL(eqBound2JsonRead.atPosition(p11), 11u);
0189   BOOST_CHECK_EQUAL(eqBound2JsonRead.atPosition(p12), 12u);
0190   BOOST_CHECK_EQUAL(eqBound2JsonRead.atPosition(p13), 13u);
0191   BOOST_CHECK_EQUAL(eqBound2JsonRead.atPosition(p14), 14u);
0192   BOOST_CHECK_EQUAL(eqBound2JsonRead.atPosition(p15), 15u);
0193   BOOST_CHECK_EQUAL(eqBound2JsonRead.atPosition(p21), 21u);
0194   BOOST_CHECK_EQUAL(eqBound2JsonRead.atPosition(p22), 22u);
0195   BOOST_CHECK_EQUAL(eqBound2JsonRead.atPosition(p23), 23u);
0196   BOOST_CHECK_EQUAL(eqBound2JsonRead.atPosition(p24), 24u);
0197   BOOST_CHECK_EQUAL(eqBound2JsonRead.atPosition(p25), 25u);
0198 }
0199 
0200 BOOST_AUTO_TEST_CASE(Grid2DSingleEntryBoundClosed) {
0201   using EqBoundEqClosed = GridAxisGenerators::EqBoundEqClosed;
0202 
0203   EqBoundEqClosed eqBoundEqClosed{
0204       {-6., 6.}, 3, {-std::numbers::pi, std::numbers::pi}, 3};
0205   // Create the grid with the provided axis generator
0206   using GridTypeEQBEQC =
0207       typename EqBoundEqClosed::template grid_type<std::size_t>;
0208   GridTypeEQBEQC eqBoundEqClosedGrid(eqBoundEqClosed());
0209 
0210   // Let's write in local coordinates
0211   using GridPoint = typename GridTypeEQBEQC::point_t;
0212 
0213   // First row access
0214   GridPoint p11{-5, -2.};
0215   GridPoint p12{0., -2};
0216   GridPoint p13{5, -2};
0217   eqBoundEqClosedGrid.atPosition(p11) = 11u;
0218   eqBoundEqClosedGrid.atPosition(p12) = 12u;
0219   eqBoundEqClosedGrid.atPosition(p13) = 13u;
0220 
0221   // Middle row access
0222   GridPoint p21{-5., 0.};
0223   GridPoint p22{0., 0.};
0224   GridPoint p23{5., 0.};
0225   eqBoundEqClosedGrid.atPosition(p21) = 21u;
0226   eqBoundEqClosedGrid.atPosition(p22) = 22u;
0227   eqBoundEqClosedGrid.atPosition(p23) = 23u;
0228 
0229   // Last row access
0230   GridPoint p31{-5., 2.};
0231   GridPoint p32{0., 2.};
0232   GridPoint p33{5., 2.};
0233   eqBoundEqClosedGrid.atPosition(p31) = 31u;
0234   eqBoundEqClosedGrid.atPosition(p32) = 32u;
0235   eqBoundEqClosedGrid.atPosition(p33) = 33u;
0236 
0237   nlohmann::json eqBoundEqClosedJson =
0238       GridJsonConverter::toJson(eqBoundEqClosedGrid);
0239 
0240   auto eqBoundEqClosedJsonRead =
0241       GridJsonConverter::fromJson<EqBoundEqClosed, std::size_t>(
0242           eqBoundEqClosedJson, eqBoundEqClosed);
0243 
0244   BOOST_CHECK_EQUAL(eqBoundEqClosedJsonRead.atPosition(p11), 11u);
0245   BOOST_CHECK_EQUAL(eqBoundEqClosedJsonRead.atPosition(p12), 12u);
0246   BOOST_CHECK_EQUAL(eqBoundEqClosedJsonRead.atPosition(p13), 13u);
0247 
0248   BOOST_CHECK_EQUAL(eqBoundEqClosedJsonRead.atPosition(p21), 21u);
0249   BOOST_CHECK_EQUAL(eqBoundEqClosedJsonRead.atPosition(p22), 22u);
0250   BOOST_CHECK_EQUAL(eqBoundEqClosedJsonRead.atPosition(p23), 23u);
0251 
0252   BOOST_CHECK_EQUAL(eqBoundEqClosedJsonRead.atPosition(p31), 31u);
0253   BOOST_CHECK_EQUAL(eqBoundEqClosedJsonRead.atPosition(p32), 32u);
0254   BOOST_CHECK_EQUAL(eqBoundEqClosedJsonRead.atPosition(p33), 33u);
0255 }
0256 
0257 namespace {
0258 template <typename ReferenceType, typename CheckTypeUniquePtr>
0259 bool checkType(const ReferenceType& /**unused*/,
0260                const CheckTypeUniquePtr& g2l) {
0261   return (dynamic_cast<const ReferenceType*>(g2l.get()) != nullptr);
0262 }
0263 
0264 template <typename SubspactTuple>
0265 void checkGlobalSubspaceTuple(const SubspactTuple& sstuple) {
0266   // Test without transform
0267   std::vector<nlohmann::json> jsspace;
0268   std::apply(
0269       [&](auto&&... vals) {
0270         (jsspace.push_back(GridAccessJsonConverter::toJson(vals)), ...);
0271       },
0272       sstuple);
0273 
0274   // Test that none of them are empty
0275   for (auto& jss : jsspace) {
0276     BOOST_CHECK(!jss.empty());
0277   }
0278 
0279   // Read back in
0280   std::vector<std::unique_ptr<const GridAccess::IGlobalToGridLocal>> sspaceRead;
0281   for (auto& jss : jsspace) {
0282     sspaceRead.push_back(
0283         GridAccessJsonConverter::globalToGridLocalFromJson(jss));
0284     if (jss["accessors"].size() == 1u) {
0285       auto delegate =
0286           GridAccessJsonConverter::globalToGridLocal1DimDelegateFromJson(jss);
0287       BOOST_CHECK(delegate.connected());
0288     } else if (jss["accessors"].size() == 2u) {
0289       auto delegate =
0290           GridAccessJsonConverter::globalToGridLocal2DimDelegateFromJson(jss);
0291       BOOST_CHECK(delegate.connected());
0292     } else {
0293       BOOST_CHECK(false);
0294     }
0295   }
0296 
0297   // Test that none of them are empty
0298   for (auto& ssp : sspaceRead) {
0299     BOOST_CHECK(ssp != nullptr);
0300   }
0301 
0302   // Check that the type is correct
0303   std::size_t irn = 0;
0304   bool good = true;
0305   std::apply(
0306       [&](auto&&... vals) {
0307         ((good = good && checkType(vals, sspaceRead[irn++])), ...);
0308       },
0309       sstuple);
0310   BOOST_CHECK(good);
0311 
0312   Transform3 tTransform;
0313   tTransform.pretranslate(Vector3{0., 0., 100.});
0314 
0315   // Test with transform
0316   std::vector<nlohmann::json> jsspaceTransform;
0317   std::apply(
0318       [&](auto... vals) {
0319         (jsspaceTransform.push_back(GridAccessJsonConverter::toJson(
0320              GridAccess::Affine3Transformed<decltype(vals)>(vals, tTransform))),
0321          ...);
0322       },
0323       sstuple);
0324 
0325   // Test that none of them are empty & everyone has a stransform
0326   for (auto& jss : jsspaceTransform) {
0327     BOOST_CHECK(!jss.empty());
0328     BOOST_CHECK(jss.find("transform") != jss.end());
0329   }
0330 
0331   // Read back in
0332   std::vector<std::unique_ptr<const GridAccess::IGlobalToGridLocal>>
0333       sspaceTransformRead;
0334   for (auto& jss : jsspaceTransform) {
0335     sspaceTransformRead.push_back(
0336         GridAccessJsonConverter::globalToGridLocalFromJson(jss));
0337   }
0338 
0339   // Test that none of them are empty
0340   for (auto& ssp : sspaceTransformRead) {
0341     BOOST_CHECK(ssp != nullptr);
0342   }
0343 
0344   // Check that the type is correct
0345   irn = 0;
0346   good = true;
0347   std::apply(
0348       [&](auto... vals) {
0349         ((good =
0350               good && checkType(GridAccess::Affine3Transformed<decltype(vals)>(
0351                                     vals, tTransform),
0352                                 sspaceTransformRead[irn++])),
0353          ...);
0354       },
0355       sstuple);
0356   BOOST_CHECK(good);
0357 }
0358 
0359 }  // namespace
0360 
0361 BOOST_AUTO_TEST_CASE(GlobalSubSpaceTests1D) {
0362   // One dimensional sub spaces
0363   const std::tuple<GridAccess::GlobalSubspace<AxisDirection::AxisX>,
0364                    GridAccess::GlobalSubspace<AxisDirection::AxisY>,
0365                    GridAccess::GlobalSubspace<AxisDirection::AxisZ>,
0366                    GridAccess::GlobalSubspace<AxisDirection::AxisR>,
0367                    GridAccess::GlobalSubspace<AxisDirection::AxisPhi>,
0368                    GridAccess::GlobalSubspace<AxisDirection::AxisEta>>
0369       sspace1D;
0370 
0371   // Check the tuple for 1D
0372   checkGlobalSubspaceTuple(sspace1D);
0373 }
0374 
0375 BOOST_AUTO_TEST_CASE(GlobalSubSpaceTests2D) {
0376   // Two dimensional sub spaces
0377   const std::tuple<
0378       GridAccess::GlobalSubspace<AxisDirection::AxisX, AxisDirection::AxisY>,
0379       GridAccess::GlobalSubspace<AxisDirection::AxisY, AxisDirection::AxisX>,
0380       GridAccess::GlobalSubspace<AxisDirection::AxisX, AxisDirection::AxisZ>,
0381       GridAccess::GlobalSubspace<AxisDirection::AxisZ, AxisDirection::AxisX>,
0382       GridAccess::GlobalSubspace<AxisDirection::AxisY, AxisDirection::AxisZ>,
0383       GridAccess::GlobalSubspace<AxisDirection::AxisZ, AxisDirection::AxisY>,
0384       GridAccess::GlobalSubspace<AxisDirection::AxisR, AxisDirection::AxisPhi>,
0385       GridAccess::GlobalSubspace<AxisDirection::AxisPhi, AxisDirection::AxisR>,
0386       GridAccess::GlobalSubspace<AxisDirection::AxisZ, AxisDirection::AxisPhi>,
0387       GridAccess::GlobalSubspace<AxisDirection::AxisPhi, AxisDirection::AxisZ>>
0388       sspace2D = {};
0389 
0390   // Check the tuple for 2D
0391   checkGlobalSubspaceTuple(sspace2D);
0392 }
0393 
0394 BOOST_AUTO_TEST_CASE(LocalSubspaceTests) {
0395   const std::tuple<GridAccess::LocalSubspace<0u>, GridAccess::LocalSubspace<1u>,
0396                    GridAccess::LocalSubspace<0u, 1u>,
0397                    GridAccess::LocalSubspace<1u, 0u>>
0398       lspace1D;
0399 
0400   // Write them to json
0401   std::vector<nlohmann::json> jlspace;
0402   std::apply(
0403       [&](auto&&... vals) {
0404         (jlspace.push_back(GridAccessJsonConverter::toJson(vals)), ...);
0405       },
0406       lspace1D);
0407 
0408   // Check that none of them is empty
0409   for (auto& jls : jlspace) {
0410     BOOST_CHECK(!jls.empty());
0411   }
0412 
0413   std::vector<std::unique_ptr<const GridAccess::IBoundToGridLocal>> lspaceRead;
0414   for (auto& jls : jlspace) {
0415     lspaceRead.push_back(
0416         GridAccessJsonConverter::boundToGridLocalFromJson(jls));
0417     if (jls["accessors"].size() == 1u) {
0418       auto delegate =
0419           GridAccessJsonConverter::boundToGridLocal1DimDelegateFromJson(jls);
0420       BOOST_CHECK(delegate.connected());
0421     } else if (jls["accessors"].size() == 2u) {
0422       auto delegate =
0423           GridAccessJsonConverter::boundToGridLocal2DimDelegateFromJson(jls);
0424       BOOST_CHECK(delegate.connected());
0425     } else {
0426       BOOST_CHECK(false);
0427     }
0428   }
0429 
0430   // Test that none of them are empty
0431   for (auto& lsp : lspaceRead) {
0432     BOOST_CHECK(lsp != nullptr);
0433   }
0434 
0435   // Check that the type is correct
0436   std::size_t irn = 0;
0437   bool good = true;
0438   std::apply(
0439       [&](auto&&... vals) {
0440         ((good = good && checkType(vals, lspaceRead[irn++])), ...);
0441       },
0442       lspace1D);
0443   BOOST_CHECK(good);
0444 }
0445 
0446 BOOST_AUTO_TEST_CASE(BoundCylinderToZPhiTest) {
0447   GridAccess::BoundCylinderToZPhi boundCylinderToZPhi(100., 10.);
0448 
0449   nlohmann::json jboundCylinderToZPhi =
0450       GridAccessJsonConverter::toJson(boundCylinderToZPhi);
0451 
0452   // Check it is not empty
0453   BOOST_CHECK(!jboundCylinderToZPhi.empty());
0454 
0455   auto boundCylinderToZPhiRead =
0456       GridAccessJsonConverter::boundToGridLocalFromJson(jboundCylinderToZPhi);
0457 
0458   // Check that it is not empty
0459   BOOST_REQUIRE(boundCylinderToZPhiRead != nullptr);
0460 
0461   const GridAccess::BoundCylinderToZPhi* bct =
0462       dynamic_cast<const GridAccess::BoundCylinderToZPhi*>(
0463           boundCylinderToZPhiRead.get());
0464 
0465   auto delegate = GridAccessJsonConverter::boundToGridLocal2DimDelegateFromJson(
0466       jboundCylinderToZPhi);
0467   BOOST_CHECK(delegate.connected());
0468 
0469   BOOST_REQUIRE(bct != nullptr);
0470   CHECK_CLOSE_ABS(bct->radius, 100., 1e-5);
0471   CHECK_CLOSE_ABS(bct->shift, 10., 1e-5);
0472 }
0473 
0474 BOOST_AUTO_TEST_SUITE_END()
0475 
0476 }  // namespace ActsTests