Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-08 08:01:24

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/tools/old/interface.hpp>
0010 #include <boost/test/unit_test.hpp>
0011 
0012 #include "Acts/Definitions/Algebra.hpp"
0013 #include "Acts/EventData/detail/TestSourceLink.hpp"
0014 #include "Acts/Geometry/CuboidVolumeBuilder.hpp"
0015 #include "Acts/Geometry/GeometryContext.hpp"
0016 #include "ActsAlignment/Kernel/Alignment.hpp"
0017 #include "ActsAlignment/Kernel/detail/AlignmentEngine.hpp"
0018 #include "ActsPlugins/Mille/ActsToMille.hpp"
0019 #include "ActsPlugins/Mille/Helpers.hpp"
0020 #include "ActsTests/CommonHelpers/AlignmentHelpers.hpp"
0021 
0022 #include <string>
0023 
0024 #include <Mille/MilleDecoder.h>
0025 #include <Mille/MilleFactory.h>
0026 
0027 using namespace Acts;
0028 using namespace ActsTests;
0029 using namespace ActsTests::AlignmentUtils;
0030 using namespace Acts::detail::Test;
0031 using namespace Acts::UnitConstants;
0032 
0033 BOOST_AUTO_TEST_CASE(ZeroFieldKalmanToMille) {
0034   /// Part 1): Build some test data.
0035   /// This is shamelessly "borrowed" from
0036   /// the existing alignment unit test.
0037 
0038   aliTestUtils utils;
0039   // Build detector
0040   TelescopeDetector detector(utils.geoCtx);
0041   const auto geometry = detector();
0042 
0043   // reconstruction propagator and fitter
0044   auto kfLogger = getDefaultLogger("KalmanFilter", Logging::INFO);
0045   const auto kfZeroPropagator =
0046       makeConstantFieldPropagator(geometry, 0_T, std::move(kfLogger));
0047   auto kfZero = KalmanFitterType(kfZeroPropagator);
0048 
0049   // alignment
0050   auto alignLogger = getDefaultLogger("Alignment", Logging::INFO);
0051   const auto alignZero =
0052       ActsAlignment::Alignment(std::move(kfZero), std::move(alignLogger));
0053 
0054   // Create 10 trajectories
0055   const auto& trajectories = createTrajectories(geometry, 10, utils);
0056 
0057   // Construct the KalmanFitter options
0058 
0059   auto extensions = getExtensions(utils);
0060   TestSourceLink::SurfaceAccessor surfaceAccessor{*geometry};
0061   extensions.surfaceAccessor
0062       .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0063   KalmanFitterOptions kfOptions(
0064       utils.geoCtx, utils.magCtx, utils.calCtx, extensions,
0065       PropagatorPlainOptions(utils.geoCtx, utils.magCtx));
0066 
0067   // Construct a non-updating alignment updater
0068   ActsAlignment::AlignedTransformUpdater voidAlignUpdater =
0069       [](SurfacePlacementBase* /*element*/, const GeometryContext& /*gctx*/,
0070          const Transform3& /*transform*/) { return true; };
0071 
0072   // Construct the alignment options
0073   ActsAlignment::AlignmentOptions<KalmanFitterOptions<VectorMultiTrajectory>>
0074       alignOptions(kfOptions, voidAlignUpdater);
0075   alignOptions.maxIterations = 1;
0076 
0077   // Set the surfaces to be aligned (fix the layer 8)
0078   unsigned int iSurface = 0;
0079   std::unordered_map<const Surface*, std::size_t> idxedAlignSurfaces;
0080   // Loop over the detector elements
0081   for (auto& det : detector.detectorStore) {
0082     const auto& surface = det->surface();
0083     if (surface.geometryId().layer() != 8) {
0084       alignOptions.alignedDetElements.push_back(det.get());
0085       idxedAlignSurfaces.emplace(&surface, iSurface);
0086       iSurface++;
0087     }
0088   }
0089 
0090   // Test the method to evaluate alignment state for a single track
0091   const auto& inputTraj = trajectories.front();
0092   kfOptions.referenceSurface = &(*inputTraj.startParameters).referenceSurface();
0093 
0094   auto evaluateRes = alignZero.evaluateTrackAlignmentState(
0095       kfOptions.geoContext, inputTraj.sourceLinks, *inputTraj.startParameters,
0096       kfOptions, idxedAlignSurfaces, ActsAlignment::AlignmentMask::All);
0097   BOOST_CHECK(evaluateRes.ok());
0098 
0099   /// Part 2: Now dump the alignment state to Mille.
0100 
0101   auto milleRecord = Mille::spawnMilleRecord("myRecord.root", true);
0102 
0103   const auto& alignState = evaluateRes.value();
0104   ActsPlugins::ActsToMille::dumpToMille(alignState, *milleRecord);
0105 
0106   // trigger file close by destroying the Mille record
0107   milleRecord->flushOutputFile();
0108   milleRecord.reset();
0109 
0110   /// Part 3: We read back the record from the binary file,
0111   /// convert it to an alignment state, and compare to
0112   /// what we started from
0113 
0114   // read back the record
0115   auto milleReader = Mille::spawnMilleReader("myRecord.root");
0116   BOOST_CHECK(milleReader->open("myRecord.root"));
0117 
0118   // Decode it back into a TrackAlignmentState
0119 
0120   ActsAlignment::detail::TrackAlignmentState millePedeState;
0121   // we need to externally supply the alignment parameter indexing logic
0122   millePedeState.alignedSurfaces = alignState.alignedSurfaces;
0123   BOOST_CHECK(ActsPlugins::ActsToMille::unpackMilleRecord(
0124                   *milleReader, millePedeState, idxedAlignSurfaces) ==
0125               Mille::MilleDecoder::ReadResult::OK);
0126 
0127   // now compare the results!
0128 
0129   BOOST_CHECK_EQUAL(millePedeState.alignmentDof, alignState.alignmentDof);
0130   BOOST_CHECK_EQUAL(millePedeState.measurementDim, alignState.measurementDim);
0131   BOOST_CHECK_EQUAL(millePedeState.trackParametersDim,
0132                     alignState.trackParametersDim);
0133 
0134   BOOST_CHECK_EQUAL(millePedeState.residual, alignState.residual);
0135   BOOST_CHECK_EQUAL(millePedeState.chi2, alignState.chi2);
0136   BOOST_CHECK_EQUAL(millePedeState.measurementCovariance,
0137                     alignState.measurementCovariance);
0138   BOOST_CHECK_EQUAL(millePedeState.projectionMatrix,
0139                     alignState.projectionMatrix);
0140 
0141   BOOST_CHECK_EQUAL(millePedeState.alignmentToResidualDerivative,
0142                     alignState.alignmentToResidualDerivative);
0143 
0144   // for the track parameter covariance, we only compare the regularised version
0145   // (differences expected in poorly constrained parameters. Also increase the
0146   // tolerance a bit.
0147   BOOST_CHECK(millePedeState.trackParametersCovariance.isApprox(
0148       ActsPlugins::ActsToMille::regulariseCovariance(
0149           alignState.trackParametersCovariance),
0150       1.e-6));
0151 
0152   // for anything derived from the TP covariance, we can also only ask for
0153   // approximate equivalence as a result.
0154   BOOST_CHECK(millePedeState.residualCovariance.isApprox(
0155       alignState.residualCovariance, 1.e-6));
0156   BOOST_CHECK(millePedeState.alignmentToChi2Derivative.isApprox(
0157       alignState.alignmentToChi2Derivative, 1.e-6));
0158   BOOST_CHECK(millePedeState.alignmentToChi2SecondDerivative.isApprox(
0159       alignState.alignmentToChi2SecondDerivative, 1.e-6));
0160 }