-
Notifications
You must be signed in to change notification settings - Fork 157
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Introduce Json Converter for Surfaces (#662)
- Loading branch information
1 parent
3ddff2e
commit 4bd3a88
Showing
6 changed files
with
371 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
Plugins/Json/include/Acts/Plugins/Json/SurfaceJsonConverter.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// This file is part of the Acts project. | ||
// | ||
// Copyright (C) 2021 CERN for the benefit of the Acts project | ||
// | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
#pragma once | ||
|
||
#include "Acts/Geometry/GeometryContext.hpp" | ||
#include "Acts/Plugins/Json/AlgebraJsonConverter.hpp" | ||
#include "Acts/Plugins/Json/SurfaceBoundsJsonConverter.hpp" | ||
#include "Acts/Surfaces/Surface.hpp" | ||
|
||
#include <string> | ||
#include <vector> | ||
|
||
#include <nlohmann/json.hpp> | ||
|
||
// Custom Json encoder/decoders. Naming is mandated by nlohman::json and thus | ||
// can not match our naming guidelines. | ||
namespace Acts { | ||
|
||
static std::vector<std::string> surfaceTypes = { | ||
"ConeSurface", "CylinderSurface", "DiscSurface", "PerigeeSurface", | ||
"PlaneSurface", "StrawSurface", "CurvilinearSurface"}; | ||
|
||
/// Non-contextual conversion of a surface | ||
/// | ||
/// @note it will take the default context | ||
void to_json(nlohmann::json& j, const Surface& surface); | ||
|
||
/// Contextual conversion of a surface | ||
/// | ||
/// @param j the json to be filled | ||
/// @param surface the surface to be converted | ||
/// @param gctx the geometry context for this | ||
void toJson(nlohmann::json& j, const Surface& surface, | ||
const Acts::GeometryContext& gctx); | ||
|
||
/// Converstion to Surface from jsonn | ||
/// | ||
/// @param j the read-in json object | ||
/// | ||
/// @return a shared_ptr to a surface object for type polymorphism | ||
std::shared_ptr<Surface> surfaceFromJson(const nlohmann::json&); | ||
|
||
/// Converstion to Surface from json in correct type | ||
/// | ||
/// The type is given as a template argument in order to be able | ||
/// to construct the correct fitting types for surfaces. | ||
/// | ||
/// @param j the read-in json object | ||
/// | ||
/// @return a shared_ptr to a typed surface object for type polymorphism | ||
template <typename surface_t, typename bounds_t> | ||
std::shared_ptr<surface_t> surfaceFromJsonT(const nlohmann::json& j) { | ||
Transform3 sTransform; | ||
nlohmann::json jtrf = j["transform"]; | ||
from_json(jtrf, sTransform); | ||
nlohmann::json jbounds = j["bounds"]; | ||
auto sBounds = surfaceBoundsFromJson<bounds_t>(jbounds); | ||
return Surface::makeShared<surface_t>(sTransform, std::move(sBounds)); | ||
} | ||
|
||
} // namespace Acts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// This file is part of the Acts project. | ||
// | ||
// Copyright (C) 2021 CERN for the benefit of the Acts project | ||
// | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
#include "Acts/Plugins/Json/SurfaceJsonConverter.hpp" | ||
|
||
#include "Acts/Surfaces/AnnulusBounds.hpp" | ||
#include "Acts/Surfaces/ConeBounds.hpp" | ||
#include "Acts/Surfaces/ConeSurface.hpp" | ||
#include "Acts/Surfaces/CylinderBounds.hpp" | ||
#include "Acts/Surfaces/CylinderSurface.hpp" | ||
#include "Acts/Surfaces/DiamondBounds.hpp" | ||
#include "Acts/Surfaces/DiscSurface.hpp" | ||
#include "Acts/Surfaces/DiscTrapezoidBounds.hpp" | ||
#include "Acts/Surfaces/EllipseBounds.hpp" | ||
#include "Acts/Surfaces/LineBounds.hpp" | ||
#include "Acts/Surfaces/PerigeeSurface.hpp" | ||
#include "Acts/Surfaces/PlaneSurface.hpp" | ||
#include "Acts/Surfaces/RadialBounds.hpp" | ||
#include "Acts/Surfaces/RectangleBounds.hpp" | ||
#include "Acts/Surfaces/StrawSurface.hpp" | ||
#include "Acts/Surfaces/TrapezoidBounds.hpp" | ||
|
||
void Acts::to_json(nlohmann::json& j, const Acts::Surface& surface) { | ||
Acts::GeometryContext gctx; | ||
toJson(j, surface, gctx); | ||
} | ||
|
||
void Acts::toJson(nlohmann::json& j, const Acts::Surface& surface, | ||
const Acts::GeometryContext& gctx) { | ||
const auto& sBounds = surface.bounds(); | ||
const auto sTransform = surface.transform(gctx); | ||
j["bounds"] = nlohmann::json(sBounds); | ||
nlohmann::json trfj; | ||
to_json(trfj, sTransform); | ||
j["transform"] = trfj; | ||
j["type"] = surfaceTypes[surface.type()]; | ||
j["geo_id"] = surface.geometryId().value(); | ||
// @todo add SurfaceMaterial converter when available | ||
} | ||
|
||
std::shared_ptr<Acts::Surface> Acts::surfaceFromJson(const nlohmann::json& j) { | ||
std::string sType = j["type"]; | ||
std::string bType = j["bounds"]["type"]; | ||
|
||
std::shared_ptr<Acts::Surface> mutableSf = nullptr; | ||
|
||
/// Unroll the types | ||
if (sType == "PlaneSurface") { | ||
if (bType == "EllipseBounds") { | ||
mutableSf = surfaceFromJsonT<Acts::PlaneSurface, Acts::EllipseBounds>(j); | ||
} else if (bType == "RectangleBounds") { | ||
mutableSf = | ||
surfaceFromJsonT<Acts::PlaneSurface, Acts::RectangleBounds>(j); | ||
} else if (bType == "TrapezoidBounds") { | ||
mutableSf = | ||
surfaceFromJsonT<Acts::PlaneSurface, Acts::TrapezoidBounds>(j); | ||
} | ||
} else if (sType == "DiscSurface") { | ||
if (bType == "AnnulusBounds") { | ||
mutableSf = surfaceFromJsonT<Acts::DiscSurface, Acts::AnnulusBounds>(j); | ||
} else if (bType == "RadialBounds") { | ||
mutableSf = surfaceFromJsonT<Acts::DiscSurface, Acts::RadialBounds>(j); | ||
} else if (bType == "DiscTrapezoidBounds") { | ||
mutableSf = | ||
surfaceFromJsonT<Acts::DiscSurface, Acts::DiscTrapezoidBounds>(j); | ||
} | ||
} else if (sType == "CylinderSurface") { | ||
mutableSf = | ||
surfaceFromJsonT<Acts::CylinderSurface, Acts::CylinderBounds>(j); | ||
} else if (sType == "ConeSurface") { | ||
mutableSf = surfaceFromJsonT<Acts::ConeSurface, Acts::ConeBounds>(j); | ||
} else if (sType == "StrawSurface") { | ||
mutableSf = surfaceFromJsonT<Acts::StrawSurface, Acts::LineBounds>(j); | ||
} else if (sType == "PerigeeSurface") { | ||
Transform3 pTransform; | ||
nlohmann::json trfj = j["transform"]; | ||
; | ||
from_json(trfj, pTransform); | ||
mutableSf = Surface::makeShared<PerigeeSurface>(pTransform); | ||
} | ||
|
||
if (mutableSf != nullptr) { | ||
GeometryIdentifier geoID(j["geo_id"]); | ||
mutableSf->assignGeometryId(geoID); | ||
// @todo add material | ||
// if (j.find("material") != j.end() and not j["material"].empty()) { | ||
// | ||
// } | ||
} | ||
|
||
return mutableSf; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
204 changes: 204 additions & 0 deletions
204
Tests/UnitTests/Plugins/Json/SurfaceJsonConverterTests.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
// This file is part of the Acts project. | ||
// | ||
// Copyright (C) 2021 CERN for the benefit of the Acts project | ||
// | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
#include <boost/test/unit_test.hpp> | ||
|
||
#include "Acts/Definitions/Algebra.hpp" | ||
#include "Acts/Geometry/GeometryIdentifier.hpp" | ||
#include "Acts/Plugins/Json/SurfaceJsonConverter.hpp" | ||
#include "Acts/Surfaces/ConeBounds.hpp" | ||
#include "Acts/Surfaces/ConeSurface.hpp" | ||
#include "Acts/Surfaces/CylinderBounds.hpp" | ||
#include "Acts/Surfaces/CylinderSurface.hpp" | ||
#include "Acts/Surfaces/DiscSurface.hpp" | ||
#include "Acts/Surfaces/LineBounds.hpp" | ||
#include "Acts/Surfaces/PerigeeSurface.hpp" | ||
#include "Acts/Surfaces/PlaneSurface.hpp" | ||
#include "Acts/Surfaces/RadialBounds.hpp" | ||
#include "Acts/Surfaces/StrawSurface.hpp" | ||
#include "Acts/Surfaces/TrapezoidBounds.hpp" | ||
|
||
#include <fstream> | ||
#include <iostream> | ||
|
||
#include <nlohmann/json.hpp> | ||
|
||
using namespace Acts; | ||
|
||
std::ofstream out; | ||
|
||
Acts::GeometryContext gctx; | ||
|
||
BOOST_AUTO_TEST_SUITE(SurfaceJsonConverter) | ||
|
||
BOOST_AUTO_TEST_CASE(ConeSurfaceRoundTripTests) { | ||
Transform3 trf(Transform3::Identity() * Translation3(0., 0., -7.)); | ||
auto cone = std::make_shared<ConeBounds>(0.123, 10., 100.); | ||
auto coneRef = Surface::makeShared<ConeSurface>(trf, cone); | ||
coneRef->assignGeometryId(GeometryIdentifier(13u)); | ||
|
||
// Test a rectangle | ||
nlohmann::json coneOut; | ||
to_json(coneOut, *coneRef); | ||
out.open("ConeSurface.json"); | ||
out << coneOut.dump(2); | ||
out.close(); | ||
|
||
auto in = std::ifstream("ConeSurface.json", | ||
std::ifstream::in | std::ifstream::binary); | ||
BOOST_CHECK(in.good()); | ||
nlohmann::json coneIn; | ||
in >> coneIn; | ||
in.close(); | ||
|
||
auto coneTest = surfaceFromJson(coneIn); | ||
|
||
BOOST_CHECK(coneTest->transform(gctx).isApprox(coneRef->transform(gctx))); | ||
BOOST_CHECK(coneTest->geometryId() == coneRef->geometryId()); | ||
BOOST_CHECK(coneTest->bounds() == coneRef->bounds()); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(DiscSurfaceRoundTripTests) { | ||
Transform3 trf(Transform3::Identity() * Translation3(0., 0., -7.)); | ||
auto ring = std::make_shared<RadialBounds>(0., 4.); | ||
auto ringDiscRef = Surface::makeShared<DiscSurface>(trf, ring); | ||
ringDiscRef->assignGeometryId(GeometryIdentifier(10u)); | ||
|
||
// Test a rectangle | ||
nlohmann::json discOut; | ||
to_json(discOut, *ringDiscRef); | ||
out.open("DiscSurface.json"); | ||
out << discOut.dump(2); | ||
out.close(); | ||
|
||
auto in = std::ifstream("DiscSurface.json", | ||
std::ifstream::in | std::ifstream::binary); | ||
BOOST_CHECK(in.good()); | ||
nlohmann::json discIn; | ||
in >> discIn; | ||
in.close(); | ||
|
||
auto ringDiscTest = surfaceFromJson(discIn); | ||
|
||
BOOST_CHECK( | ||
ringDiscTest->transform(gctx).isApprox(ringDiscRef->transform(gctx))); | ||
BOOST_CHECK(ringDiscTest->geometryId() == ringDiscRef->geometryId()); | ||
BOOST_CHECK(ringDiscTest->bounds() == ringDiscRef->bounds()); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(CylinderSurfaceRoundTripTests) { | ||
Transform3 trf(Transform3::Identity() * Translation3(0., 0., -7.)); | ||
auto tube = std::make_shared<CylinderBounds>(5., 20.); | ||
auto cylinderRef = Surface::makeShared<CylinderSurface>(trf, tube); | ||
cylinderRef->assignGeometryId(GeometryIdentifier(11u)); | ||
|
||
// Test a rectangle | ||
nlohmann::json cylinderOut; | ||
to_json(cylinderOut, *cylinderRef); | ||
out.open("CylinderSurface.json"); | ||
out << cylinderOut.dump(2); | ||
out.close(); | ||
|
||
auto in = std::ifstream("CylinderSurface.json", | ||
std::ifstream::in | std::ifstream::binary); | ||
BOOST_CHECK(in.good()); | ||
nlohmann::json cylinderIn; | ||
in >> cylinderIn; | ||
in.close(); | ||
|
||
auto cylinderTest = surfaceFromJson(cylinderIn); | ||
|
||
BOOST_CHECK( | ||
cylinderTest->transform(gctx).isApprox(cylinderRef->transform(gctx))); | ||
BOOST_CHECK(cylinderTest->geometryId() == cylinderRef->geometryId()); | ||
BOOST_CHECK(cylinderTest->bounds() == cylinderRef->bounds()); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(PlaneSurfaceRoundTripTests) { | ||
Transform3 trf(Transform3::Identity() * Translation3(0., 0., -7.)); | ||
auto trapezoid = std::make_shared<TrapezoidBounds>(2., 3., 4.); | ||
auto trapezoidPlaneRef = Surface::makeShared<PlaneSurface>(trf, trapezoid); | ||
trapezoidPlaneRef->assignGeometryId(GeometryIdentifier(9u)); | ||
|
||
// Test a rectangle | ||
nlohmann::json planeOut; | ||
to_json(planeOut, *trapezoidPlaneRef); | ||
out.open("PlaneSurface.json"); | ||
out << planeOut.dump(2); | ||
out.close(); | ||
|
||
auto in = std::ifstream("PlaneSurface.json", | ||
std::ifstream::in | std::ifstream::binary); | ||
BOOST_CHECK(in.good()); | ||
nlohmann::json planeIn; | ||
in >> planeIn; | ||
in.close(); | ||
|
||
auto trapezoidPlaneTest = surfaceFromJson(planeIn); | ||
|
||
BOOST_CHECK(trapezoidPlaneTest->transform(gctx).isApprox( | ||
trapezoidPlaneRef->transform(gctx))); | ||
BOOST_CHECK(trapezoidPlaneTest->geometryId() == | ||
trapezoidPlaneRef->geometryId()); | ||
BOOST_CHECK(trapezoidPlaneTest->bounds() == trapezoidPlaneRef->bounds()); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(StrawSurfaceRoundTripTests) { | ||
Transform3 trf(Transform3::Identity() * Translation3(0., 0., -7.)); | ||
auto straw = std::make_shared<LineBounds>(1., 100.); | ||
auto strawRef = Surface::makeShared<StrawSurface>(trf, straw); | ||
strawRef->assignGeometryId(GeometryIdentifier(12u)); | ||
|
||
// Test a rectangle | ||
nlohmann::json strawOut; | ||
to_json(strawOut, *strawRef); | ||
out.open("StrawSurface.json"); | ||
out << strawOut.dump(2); | ||
out.close(); | ||
|
||
auto in = std::ifstream("StrawSurface.json", | ||
std::ifstream::in | std::ifstream::binary); | ||
BOOST_CHECK(in.good()); | ||
nlohmann::json strawIn; | ||
in >> strawIn; | ||
in.close(); | ||
|
||
auto strawTest = surfaceFromJson(strawIn); | ||
|
||
BOOST_CHECK(strawTest->transform(gctx).isApprox(strawRef->transform(gctx))); | ||
BOOST_CHECK(strawTest->geometryId() == strawRef->geometryId()); | ||
BOOST_CHECK(strawTest->bounds() == strawRef->bounds()); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(PerigeeRoundTripTests) { | ||
Transform3 trf(Transform3::Identity() * Translation3(-1., -2., -7.)); | ||
auto perigeeRef = Surface::makeShared<PerigeeSurface>(trf); | ||
perigeeRef->assignGeometryId(GeometryIdentifier(99u)); | ||
|
||
// Test a rectangle | ||
nlohmann::json perigeeOut; | ||
to_json(perigeeOut, *perigeeRef); | ||
out.open("PerigeeSurface.json"); | ||
out << perigeeOut.dump(2); | ||
out.close(); | ||
|
||
auto in = std::ifstream("PerigeeSurface.json", | ||
std::ifstream::in | std::ifstream::binary); | ||
BOOST_CHECK(in.good()); | ||
nlohmann::json perigeeIn; | ||
in >> perigeeIn; | ||
in.close(); | ||
|
||
auto perigeeTest = surfaceFromJson(perigeeIn); | ||
|
||
BOOST_CHECK( | ||
perigeeTest->transform(gctx).isApprox(perigeeRef->transform(gctx))); | ||
BOOST_CHECK(perigeeTest->geometryId() == perigeeRef->geometryId()); | ||
} | ||
|
||
BOOST_AUTO_TEST_SUITE_END() |