diff --git a/Core/include/Acts/TrackFinding/TrackSelector.hpp b/Core/include/Acts/TrackFinding/TrackSelector.hpp index 5a2cf53df27..fe4287a38b0 100644 --- a/Core/include/Acts/TrackFinding/TrackSelector.hpp +++ b/Core/include/Acts/TrackFinding/TrackSelector.hpp @@ -80,6 +80,10 @@ class TrackSelector { std::size_t maxSharedHits = std::numeric_limits::max(); double maxChi2 = inf; + /// Whether a reference surface is required for the track + /// If false, the parameter cuts are not evaluated + bool requireReferenceSurface = true; + // Defaults to: no cut MeasurementCounter measurementCounter; @@ -447,22 +451,33 @@ bool TrackSelector::isValidTrack(const track_proxy_t& track) const { const Config& cuts = *cutsPtr; - return track.hasReferenceSurface() && - within(track.transverseMomentum(), cuts.ptMin, cuts.ptMax) && - (!m_isUnbinned || (within(absEta(), cuts.absEtaMin, cuts.absEtaMax) && - within(_eta, cuts.etaMin, cuts.etaMax))) && - within(track.phi(), cuts.phiMin, cuts.phiMax) && - within(track.loc0(), cuts.loc0Min, cuts.loc0Max) && - within(track.loc1(), cuts.loc1Min, cuts.loc1Max) && - within(track.time(), cuts.timeMin, cuts.timeMax) && - checkMin(track.nMeasurements(), cuts.minMeasurements) && - checkMax(track.nHoles(), cuts.maxHoles) && - checkMax(track.nOutliers(), cuts.maxOutliers) && - checkMax(track.nHoles() + track.nOutliers(), - cuts.maxHolesAndOutliers) && - checkMax(track.nSharedHits(), cuts.maxSharedHits) && - checkMax(track.chi2(), cuts.maxChi2) && - cuts.measurementCounter.isValidTrack(track); + auto parameterCuts = [&]() { + return within(track.transverseMomentum(), cuts.ptMin, cuts.ptMax) && + (!m_isUnbinned || + (within(absEta(), cuts.absEtaMin, cuts.absEtaMax) && + within(_eta, cuts.etaMin, cuts.etaMax))) && + within(track.phi(), cuts.phiMin, cuts.phiMax) && + within(track.loc0(), cuts.loc0Min, cuts.loc0Max) && + within(track.loc1(), cuts.loc1Min, cuts.loc1Max) && + within(track.time(), cuts.timeMin, cuts.timeMax); + }; + + auto trackCuts = [&]() { + return checkMin(track.nMeasurements(), cuts.minMeasurements) && + checkMax(track.nHoles(), cuts.maxHoles) && + checkMax(track.nOutliers(), cuts.maxOutliers) && + checkMax(track.nHoles() + track.nOutliers(), + cuts.maxHolesAndOutliers) && + checkMax(track.nSharedHits(), cuts.maxSharedHits) && + checkMax(track.chi2(), cuts.maxChi2) && + cuts.measurementCounter.isValidTrack(track); + }; + + if (cuts.requireReferenceSurface) { + return track.hasReferenceSurface() && parameterCuts() && trackCuts(); + } else { + return trackCuts(); + } } inline TrackSelector::TrackSelector( diff --git a/Examples/Algorithms/TrackFinding/src/MuonHoughSeeder.cpp b/Examples/Algorithms/TrackFinding/src/MuonHoughSeeder.cpp index b074d14ab91..dda3349d254 100644 --- a/Examples/Algorithms/TrackFinding/src/MuonHoughSeeder.cpp +++ b/Examples/Algorithms/TrackFinding/src/MuonHoughSeeder.cpp @@ -88,10 +88,9 @@ ActsExamples::ProcessCode ActsExamples::MuonHoughSeeder::execute( // create the function parametrising the drift radius uncertainty auto houghWidth_fromDC = [](double, const DriftCircle& DC) { - return std::min(DC.rDriftError() * 3., - 1.0); // scale reported errors up to at least 1mm or 3 - // times the reported error as drift circle calib not - // fully reliable at this stage + // scale reported errors up to at least 1mm or 3 times the reported error as + // drift circle calib not fully reliable at this stage + return std::min(DC.rDriftError() * 3., 1.0); }; // store the true parameters @@ -100,12 +99,12 @@ ActsExamples::ProcessCode ActsExamples::MuonHoughSeeder::execute( // instantiate the hough plane Acts::HoughTransformUtils::HoughPlane houghPlane(planeCfg); - // also insantiate the peak finder + // also instantiate the peak finder Acts::HoughTransformUtils::PeakFinders::IslandsAroundMax< Acts::GeometryIdentifier::Value> peakFinder(peakFinderCfg); - // loop pver true hirs + // loop over true hits for (auto& SH : gotSH) { // read the identifier MuonMdtIdentifierFields detailedInfo = @@ -113,10 +112,9 @@ ActsExamples::ProcessCode ActsExamples::MuonHoughSeeder::execute( // store the true parameters truePatterns.emplace_back(SH.direction().y() / SH.direction().z(), SH.fourPosition().y()); - // std::cout<<"station name=" << - // static_cast(SH.stationName)< -#include -#include #include -#include -#include #include -#include #include #include @@ -138,6 +129,11 @@ class MeasurementContainer { return getMeasurement(addMeasurement(Size, geometryId)); } + template + VariableProxy copyMeasurement(const OtherDerived& other); + template + FixedProxy copyMeasurement(const OtherDerived& other); + template VariableProxy emplaceMeasurement(std::uint8_t size, Acts::GeometryIdentifier geometryId, @@ -494,6 +490,22 @@ class VariableMeasurementProxy } }; +template +MeasurementContainer::VariableProxy MeasurementContainer::copyMeasurement( + const OtherDerived& other) { + VariableProxy meas = makeMeasurement(other.size(), other.geometryId()); + meas.copyFrom(other); + return meas; +} + +template +MeasurementContainer::FixedProxy MeasurementContainer::copyMeasurement( + const OtherDerived& other) { + FixedProxy meas = makeMeasurement(other.geometryId()); + meas.copyFrom(other); + return meas; +} + template MeasurementContainer::VariableProxy MeasurementContainer::emplaceMeasurement( std::uint8_t size, Acts::GeometryIdentifier geometryId, Args&&... args) { diff --git a/Examples/Framework/include/ActsExamples/EventData/MeasurementConcept.hpp b/Examples/Framework/include/ActsExamples/EventData/MeasurementConcept.hpp index 14627a78c53..9394b1bf992 100644 --- a/Examples/Framework/include/ActsExamples/EventData/MeasurementConcept.hpp +++ b/Examples/Framework/include/ActsExamples/EventData/MeasurementConcept.hpp @@ -8,7 +8,6 @@ #pragma once -#include "Acts/EventData/SourceLink.hpp" #include "Acts/Geometry/GeometryIdentifier.hpp" #include @@ -23,4 +22,5 @@ concept MeasurementConcept = requires(const T& m) { { m.parameters() }; { m.covariance() }; }; + } // namespace ActsExamples diff --git a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp index 4aef2c30e56..4561bc61db0 100644 --- a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp +++ b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp @@ -370,8 +370,8 @@ ProcessCode EDM4hepReader::read(const AlgorithmContext& ctx) { for (auto it = hitsByParticle.begin(), end = hitsByParticle.end(); it != end; it = hitsByParticle.upper_bound(it->first)) { - std::cout << "Particle " << it->first << " has " - << hitsByParticle.count(it->first) << " hits" << std::endl; + ACTS_DEBUG("Particle " << it->first << " has " + << hitsByParticle.count(it->first) << " hits"); std::vector hitIndices; hitIndices.reserve(hitsByParticle.count(it->first)); diff --git a/Examples/Io/Json/CMakeLists.txt b/Examples/Io/Json/CMakeLists.txt index 255d862881f..5461f5dd98d 100644 --- a/Examples/Io/Json/CMakeLists.txt +++ b/Examples/Io/Json/CMakeLists.txt @@ -4,7 +4,6 @@ add_library( src/JsonGeometryList.cpp src/JsonMaterialWriter.cpp src/JsonSurfacesWriter.cpp - src/JsonSurfacesReader.cpp src/JsonDigitizationConfig.cpp ) target_include_directories( diff --git a/Examples/Io/Root/src/RootMaterialTrackReader.cpp b/Examples/Io/Root/src/RootMaterialTrackReader.cpp index b7e5e0ef4f2..dc8a48e137e 100644 --- a/Examples/Io/Root/src/RootMaterialTrackReader.cpp +++ b/Examples/Io/Root/src/RootMaterialTrackReader.cpp @@ -83,9 +83,6 @@ RootMaterialTrackReader::RootMaterialTrackReader(const Config& config, ACTS_DEBUG("The full chain has " << nentries << " entries for " << m_events << " events this corresponds to a batch size of: " << m_batchSize); - std::cout << "The full chain has " << nentries << " entries for " << m_events - << " events this corresponds to a batch size of: " << m_batchSize - << std::endl; // Sort the entry numbers of the events { diff --git a/Examples/Python/python/acts/examples/reconstruction.py b/Examples/Python/python/acts/examples/reconstruction.py index bc1b1d4df9d..0d1131d45cf 100644 --- a/Examples/Python/python/acts/examples/reconstruction.py +++ b/Examples/Python/python/acts/examples/reconstruction.py @@ -123,10 +123,42 @@ "maxSharedHits", "maxChi2", "nMeasurementsGroupMin", + "requireReferenceSurface", ], - defaults=[(None, None)] * 7 + [None] * 7, + defaults=[(None, None)] * 7 + [None] * 8, ) + +def trackSelectorDefaultKWArgs(c): + """ + Encapsulate this boilerplate code into a function so different uses do not get out of sync + """ + return acts.examples.defaultKWArgs( + loc0Min=c.loc0[0], + loc0Max=c.loc0[1], + loc1Min=c.loc1[0], + loc1Max=c.loc1[1], + timeMin=c.time[0], + timeMax=c.time[1], + phiMin=c.phi[0], + phiMax=c.phi[1], + etaMin=c.eta[0], + etaMax=c.eta[1], + absEtaMin=c.absEta[0], + absEtaMax=c.absEta[1], + ptMin=c.pt[0], + ptMax=c.pt[1], + minMeasurements=c.nMeasurementsMin, + maxHoles=c.maxHoles, + maxOutliers=c.maxOutliers, + maxHolesAndOutliers=c.maxHolesAndOutliers, + maxSharedHits=c.maxSharedHits, + maxChi2=c.maxChi2, + measurementCounter=c.nMeasurementsGroupMin, + requireReferenceSurface=c.requireReferenceSurface, + ) + + CkfConfig = namedtuple( "CkfConfig", [ @@ -1424,32 +1456,10 @@ def addCKFTracks( else trackSelectorConfig ) ) + + overwriteArgs = dict() if len(tslist) == 1 else dict(absEtaMax=None) cutSets = [ - acts.TrackSelector.Config( - **acts.examples.defaultKWArgs( - loc0Min=c.loc0[0], - loc0Max=c.loc0[1], - loc1Min=c.loc1[0], - loc1Max=c.loc1[1], - timeMin=c.time[0], - timeMax=c.time[1], - phiMin=c.phi[0], - phiMax=c.phi[1], - etaMin=c.eta[0], - etaMax=c.eta[1], - absEtaMin=c.absEta[0], - absEtaMax=c.absEta[1] if len(tslist) == 1 else None, - ptMin=c.pt[0], - ptMax=c.pt[1], - minMeasurements=c.nMeasurementsMin, - maxHoles=c.maxHoles, - maxOutliers=c.maxOutliers, - maxHolesAndOutliers=c.maxHolesAndOutliers, - maxSharedHits=c.maxSharedHits, - maxChi2=c.maxChi2, - measurementCounter=c.nMeasurementsGroupMin, - ) - ) + acts.TrackSelector.Config(**(trackSelectorDefaultKWArgs(c) | overwriteArgs)) for c in tslist ] if len(tslist) == 0: @@ -1702,23 +1712,7 @@ def addTrackSelection( # single cut config for implicit single bin eta configuration selectorConfig = acts.TrackSelector.Config( - **acts.examples.defaultKWArgs( - loc0Min=trackSelectorConfig.loc0[0], - loc0Max=trackSelectorConfig.loc0[1], - loc1Min=trackSelectorConfig.loc1[0], - loc1Max=trackSelectorConfig.loc1[1], - timeMin=trackSelectorConfig.time[0], - timeMax=trackSelectorConfig.time[1], - phiMin=trackSelectorConfig.phi[0], - phiMax=trackSelectorConfig.phi[1], - etaMin=trackSelectorConfig.eta[0], - etaMax=trackSelectorConfig.eta[1], - absEtaMin=trackSelectorConfig.absEta[0], - absEtaMax=trackSelectorConfig.absEta[1], - ptMin=trackSelectorConfig.pt[0], - ptMax=trackSelectorConfig.pt[1], - minMeasurements=trackSelectorConfig.nMeasurementsMin, - ) + **trackSelectorDefaultKWArgs(trackSelectorConfig) ) trackSelector = acts.examples.TrackSelectorAlgorithm( diff --git a/Examples/Python/src/Detector.cpp b/Examples/Python/src/Detector.cpp index 833364301a7..94770ce7283 100644 --- a/Examples/Python/src/Detector.cpp +++ b/Examples/Python/src/Detector.cpp @@ -221,6 +221,12 @@ void addDetector(Context& ctx) { patchKwargsConstructor(c); } + + { + py::class_>( + mex, "DetectorElementBase"); + } } } // namespace Acts::Python diff --git a/Examples/Python/src/ExampleAlgorithms.cpp b/Examples/Python/src/ExampleAlgorithms.cpp index 7d9007183e8..411973d147e 100644 --- a/Examples/Python/src/ExampleAlgorithms.cpp +++ b/Examples/Python/src/ExampleAlgorithms.cpp @@ -109,6 +109,7 @@ void addExampleAlgorithms(Context& ctx) { ACTS_PYTHON_MEMBER(maxSharedHits); ACTS_PYTHON_MEMBER(maxChi2); ACTS_PYTHON_MEMBER(measurementCounter); + ACTS_PYTHON_MEMBER(requireReferenceSurface); ACTS_PYTHON_STRUCT_END(); pythonRangeProperty(c, "loc0", &Config::loc0Min, &Config::loc0Max); diff --git a/Examples/Python/src/Json.cpp b/Examples/Python/src/Json.cpp index cbf9bfb6581..1eb1d83bfc0 100644 --- a/Examples/Python/src/Json.cpp +++ b/Examples/Python/src/Json.cpp @@ -11,13 +11,13 @@ #include "Acts/Detector/ProtoDetector.hpp" #include "Acts/Plugins/Json/DetectorJsonConverter.hpp" #include "Acts/Plugins/Json/JsonMaterialDecorator.hpp" +#include "Acts/Plugins/Json/JsonSurfacesReader.hpp" #include "Acts/Plugins/Json/MaterialMapJsonConverter.hpp" #include "Acts/Plugins/Json/ProtoDetectorJsonConverter.hpp" #include "Acts/Plugins/Python/Utilities.hpp" #include "Acts/Utilities/Logger.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" #include "ActsExamples/Io/Json/JsonMaterialWriter.hpp" -#include "ActsExamples/Io/Json/JsonSurfacesReader.hpp" #include "ActsExamples/Io/Json/JsonSurfacesWriter.hpp" #include "ActsExamples/Io/Json/JsonTrackParamsLookupReader.hpp" #include "ActsExamples/Io/Json/JsonTrackParamsLookupWriter.hpp" @@ -204,21 +204,29 @@ void addJson(Context& ctx) { } { - auto sjOptions = py::class_( - mex, "SurfaceJsonOptions") - .def(py::init<>()); + auto sjOptions = + py::class_(m, "SurfaceJsonOptions") + .def(py::init<>()); - ACTS_PYTHON_STRUCT_BEGIN(sjOptions, - ActsExamples::JsonSurfacesReader::Options); + ACTS_PYTHON_STRUCT_BEGIN(sjOptions, Acts::JsonSurfacesReader::Options); ACTS_PYTHON_MEMBER(inputFile); ACTS_PYTHON_MEMBER(jsonEntryPath); ACTS_PYTHON_STRUCT_END(); - mex.def("readSurfaceHierarchyMapFromJson", - ActsExamples::JsonSurfacesReader::readHierarchyMap); + m.def("readSurfaceHierarchyMapFromJson", + Acts::JsonSurfacesReader::readHierarchyMap); - mex.def("readSurfaceVectorFromJson", - ActsExamples::JsonSurfacesReader::readVector); + m.def("readSurfaceVectorFromJson", Acts::JsonSurfacesReader::readVector); + + py::class_>( + m, "JsonDetectorElement") + .def("surface", [](Acts::JsonDetectorElement& self) { + return self.surface().getSharedPtr(); + }); + + m.def("readDetectorElementsFromJson", + Acts::JsonSurfacesReader::readDetectorElements); } { diff --git a/Plugins/Json/CMakeLists.txt b/Plugins/Json/CMakeLists.txt index 0d3ff9875ee..20634d2bfe5 100644 --- a/Plugins/Json/CMakeLists.txt +++ b/Plugins/Json/CMakeLists.txt @@ -22,6 +22,8 @@ add_library( src/VolumeJsonConverter.cpp src/AmbiguityConfigJsonConverter.cpp src/DetrayJsonHelper.cpp + src/JsonDetectorElement.cpp + src/JsonSurfacesReader.cpp ) target_include_directories( ActsPluginJson diff --git a/Plugins/Json/include/Acts/Plugins/Json/JsonDetectorElement.hpp b/Plugins/Json/include/Acts/Plugins/Json/JsonDetectorElement.hpp new file mode 100644 index 00000000000..34c5a5b173a --- /dev/null +++ b/Plugins/Json/include/Acts/Plugins/Json/JsonDetectorElement.hpp @@ -0,0 +1,38 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/. +#pragma once + +#include "Acts/Geometry/DetectorElementBase.hpp" + +#include + +namespace Acts { + +/// A implementation of a detector element, that is constructed from a +/// JSON description of a surface. The idea behind this is that it helps +/// importing whole tracking geometries from JSON files. In some parts of +/// the codebase, the existence of a detector element associated to a surface +/// has a specific meaning (e.g., flags surfaces as sensitive). +class JsonDetectorElement : public DetectorElementBase { + public: + JsonDetectorElement(const nlohmann::json &jSurface, double thickness); + + Surface &surface() override; + const Surface &surface() const override; + + double thickness() const override; + + const Transform3 &transform(const GeometryContext &gctx) const override; + + private: + std::shared_ptr m_surface; + Transform3 m_transform{}; + double m_thickness{}; +}; + +} // namespace Acts diff --git a/Examples/Io/Json/include/ActsExamples/Io/Json/JsonSurfacesReader.hpp b/Plugins/Json/include/Acts/Plugins/Json/JsonSurfacesReader.hpp similarity index 58% rename from Examples/Io/Json/include/ActsExamples/Io/Json/JsonSurfacesReader.hpp rename to Plugins/Json/include/Acts/Plugins/Json/JsonSurfacesReader.hpp index 50bbf15d35f..17822c24401 100644 --- a/Examples/Io/Json/include/ActsExamples/Io/Json/JsonSurfacesReader.hpp +++ b/Plugins/Json/include/Acts/Plugins/Json/JsonSurfacesReader.hpp @@ -9,6 +9,7 @@ #pragma once #include "Acts/Geometry/GeometryHierarchyMap.hpp" +#include "Acts/Plugins/Json/JsonDetectorElement.hpp" #include #include @@ -18,9 +19,11 @@ namespace Acts { class Surface; } -namespace ActsExamples::JsonSurfacesReader { +namespace Acts::JsonSurfacesReader { /// @brief Options specification for surface reading +/// The file should contain an array of json surfaces +/// as produced by the SurfaceJsonConverter tools struct Options { /// @brief Which input file to read from std::string inputFile = ""; @@ -29,6 +32,7 @@ struct Options { }; /// @brief Read the surfaces from the input file +/// For details on the file format see the options struct /// /// @param options specifies which file and what to read /// @@ -37,10 +41,22 @@ Acts::GeometryHierarchyMap> readHierarchyMap( const Options& options); /// @brief Read the flat surfaces from the input file +/// For details on the file format see the options struct /// -/// @param inputFile is the input file to read from +/// @param options options for surface reading /// /// @return a vector of surfaces std::vector> readVector(const Options& options); -} // namespace ActsExamples::JsonSurfacesReader +/// @brief Read the surfaces from the input file and create +/// detector elements +/// For details on the file format see the options struct +/// +/// @param options options for surface reading +/// @param thickness the thickness used to construct the detector element +/// +/// @return a vector of surfaces +std::vector> readDetectorElements( + const Options& options, double thickness); + +} // namespace Acts::JsonSurfacesReader diff --git a/Plugins/Json/src/JsonDetectorElement.cpp b/Plugins/Json/src/JsonDetectorElement.cpp new file mode 100644 index 00000000000..5c1b4568ca5 --- /dev/null +++ b/Plugins/Json/src/JsonDetectorElement.cpp @@ -0,0 +1,41 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/. + +#include "Acts/Plugins/Json/JsonDetectorElement.hpp" + +#include "Acts/Plugins/Json/AlgebraJsonConverter.hpp" +#include "Acts/Plugins/Json/SurfaceJsonConverter.hpp" + +namespace Acts { + +JsonDetectorElement::JsonDetectorElement(const nlohmann::json &jSurface, + double thickness) + : m_thickness(thickness) { + m_surface = Acts::SurfaceJsonConverter::fromJson(jSurface); + m_transform = Transform3JsonConverter::fromJson(jSurface["transform"]); + m_surface->assignDetectorElement(*this); +} + +const Surface &JsonDetectorElement::surface() const { + return *m_surface; +} + +Surface &JsonDetectorElement::surface() { + return *m_surface; +} + +const Transform3 &JsonDetectorElement::transform( + const GeometryContext & /*gctx*/) const { + return m_transform; +} + +double JsonDetectorElement::thickness() const { + return m_thickness; +} + +} // namespace Acts diff --git a/Examples/Io/Json/src/JsonSurfacesReader.cpp b/Plugins/Json/src/JsonSurfacesReader.cpp similarity index 75% rename from Examples/Io/Json/src/JsonSurfacesReader.cpp rename to Plugins/Json/src/JsonSurfacesReader.cpp index 469c9828d46..fcee0ee7b86 100644 --- a/Examples/Io/Json/src/JsonSurfacesReader.cpp +++ b/Plugins/Json/src/JsonSurfacesReader.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/Io/Json/JsonSurfacesReader.hpp" +#include "Acts/Plugins/Json/JsonSurfacesReader.hpp" #include "Acts/Geometry/GeometryIdentifier.hpp" #include "Acts/Plugins/Json/ActsJson.hpp" @@ -17,7 +17,7 @@ #include #include -namespace ActsExamples { +namespace Acts { Acts::GeometryHierarchyMap> JsonSurfacesReader::readHierarchyMap( @@ -73,4 +73,27 @@ std::vector> JsonSurfacesReader::readVector( return surfaces; } -} // namespace ActsExamples +std::vector> +JsonSurfacesReader::readDetectorElements(const Options& options, + double thickness = 0.0) { + nlohmann::json j; + { + std::ifstream in(options.inputFile); + in >> j; + } + + // Walk down the path to the surface entries + nlohmann::json jSurfaces = j; + for (const auto& jep : options.jsonEntryPath) { + jSurfaces = jSurfaces[jep]; + } + + std::vector> elements; + for (const auto& jSurface : jSurfaces) { + elements.emplace_back( + std::make_shared(jSurface, thickness)); + } + return elements; +} + +} // namespace Acts diff --git a/Tests/UnitTests/Plugins/Json/CMakeLists.txt b/Tests/UnitTests/Plugins/Json/CMakeLists.txt index 141f86fb3fe..82ad95611ed 100644 --- a/Tests/UnitTests/Plugins/Json/CMakeLists.txt +++ b/Tests/UnitTests/Plugins/Json/CMakeLists.txt @@ -16,3 +16,4 @@ add_unittest(SurfaceBoundsJsonConverter SurfaceBoundsJsonConverterTests.cpp) add_unittest(SurfaceJsonConverter SurfaceJsonConverterTests.cpp) add_unittest(VolumeBoundsJsonConverter VolumeBoundsJsonConverterTests.cpp) add_unittest(TrackParametersJsonConverter TrackParametersJsonConverterTests.cpp) +add_unittest(JsonSurfacesReader JsonSurfacesReaderTests.cpp) diff --git a/Tests/UnitTests/Plugins/Json/JsonSurfacesReaderTests.cpp b/Tests/UnitTests/Plugins/Json/JsonSurfacesReaderTests.cpp new file mode 100644 index 00000000000..e70bad6c7bf --- /dev/null +++ b/Tests/UnitTests/Plugins/Json/JsonSurfacesReaderTests.cpp @@ -0,0 +1,98 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/. + +#include +#include + +#include "Acts/Definitions/Algebra.hpp" +#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" +#include "Acts/Plugins/Json/JsonSurfacesReader.hpp" +#include "Acts/Plugins/Json/SurfaceJsonConverter.hpp" +#include "Acts/Surfaces/PlaneSurface.hpp" +#include "Acts/Surfaces/RectangleBounds.hpp" +#include "Acts/Utilities/Zip.hpp" + +#include +#include +#include + +#include +#include + +const std::vector> surfaces = []() { + std::vector> v; + + for (int i = 0; i < 3; ++i) { + auto bounds = std::make_shared(1.0, 1.0); + Acts::Transform3 transform = Acts::Transform3::Identity(); + transform.translate(Acts::Vector3::Random()); + Acts::Vector3 randomAngles = Acts::Vector3::Random(); + Acts::SquareMatrix3 rotMatrix; + rotMatrix = Eigen::AngleAxis(randomAngles[0], Acts::Vector3::UnitX()) * + Eigen::AngleAxis(randomAngles[1], Acts::Vector3::UnitY()) * + Eigen::AngleAxis(randomAngles[2], Acts::Vector3::UnitZ()); + transform.rotate(rotMatrix); + v.push_back( + Acts::Surface::makeShared(transform, bounds)); + } + + return v; +}(); + +const std::string filename = "json_surfaces_reader_tests.json"; + +struct FileFixture { + FileFixture() { + nlohmann::json js = nlohmann::json::array(); + + for (const auto &s : surfaces) { + js.push_back(Acts::SurfaceJsonConverter::toJson({}, *s)); + } + + nlohmann::json j; + j["foo"] = js; + + std::ofstream f(filename); + f << j.dump(2); + } + + ~FileFixture() { std::filesystem::remove(filename); } +}; + +FileFixture fileFixture; + +BOOST_AUTO_TEST_CASE(surface_reading_test) { + auto readBackSurfaces = + Acts::JsonSurfacesReader::readVector({filename, {"foo"}}); + + BOOST_REQUIRE_EQUAL(surfaces.size(), readBackSurfaces.size()); + for (auto [refSurface, surface] : Acts::zip(surfaces, readBackSurfaces)) { + BOOST_CHECK( + refSurface->transform({}).isApprox(surface->transform({}), 1.e-4)); + BOOST_CHECK(refSurface->center({}).isApprox(surface->center({}), 1.e-4)); + BOOST_CHECK_EQUAL(refSurface->type(), surface->type()); + BOOST_CHECK_EQUAL(refSurface->bounds().type(), surface->bounds().type()); + } +} + +BOOST_AUTO_TEST_CASE(json_detelement_reading_test) { + auto readBackDetElements = + Acts::JsonSurfacesReader::readDetectorElements({filename, {"foo"}}, 1.0); + + BOOST_REQUIRE_EQUAL(surfaces.size(), readBackDetElements.size()); + for (auto [refSurface, detElement] : + Acts::zip(surfaces, readBackDetElements)) { + auto surface = &detElement->surface(); + BOOST_CHECK( + refSurface->transform({}).isApprox(surface->transform({}), 1.e-4)); + BOOST_CHECK(refSurface->center({}).isApprox(surface->center({}), 1.e-4)); + BOOST_CHECK_EQUAL(refSurface->type(), surface->type()); + BOOST_CHECK_EQUAL(refSurface->bounds().type(), surface->bounds().type()); + } +} diff --git a/docs/_extensions/lazy_autodoc.py b/docs/_extensions/lazy_autodoc.py index 6034fa7d0df..3c9513c4268 100644 --- a/docs/_extensions/lazy_autodoc.py +++ b/docs/_extensions/lazy_autodoc.py @@ -117,6 +117,7 @@ def run() -> None: "Acts::Logging::DefaultFilterPolicy", "Acts::Logging::DefaultPrintPolicy", "Acts::SourceLink", + "Acts::JsonDetectorElement", } role_instances["func"] = {