Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:43

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