|
| 1 | +// This file is part of the ACTS project. |
| 2 | +// |
| 3 | +// Copyright (C) 2016 CERN for the benefit of the ACTS project |
| 4 | +// |
| 5 | +// This Source Code Form is subject to the terms of the Mozilla Public |
| 6 | +// License, v. 2.0. If a copy of the MPL was not distributed with this |
| 7 | +// file, You can obtain one at https://mozilla.org/MPL/2.0/. |
| 8 | + |
| 9 | +#pragma once |
| 10 | + |
| 11 | +#include "Acts/EventData/StripSpacePointCalibrationDetails.hpp" |
| 12 | +#include "Acts/Utilities/detail/StdArrayLinalg.hpp" |
| 13 | + |
| 14 | +#include <cmath> |
| 15 | + |
| 16 | +namespace Acts::detail { |
| 17 | + |
| 18 | +// Intentionally not using Eigen here as there is a noticeable performance |
| 19 | +// (10-20%) penalty for small vector sizes. |
| 20 | + |
| 21 | +inline OuterStripSpacePointCalibrationDetailsDerived |
| 22 | +deriveOuterStripSpacePointCalibrationDetails(const std::array<float, 3>& ihv, |
| 23 | + const std::array<float, 3>& ohv, |
| 24 | + const std::array<float, 3>& iosv, |
| 25 | + const std::array<float, 3>& oc) { |
| 26 | + OuterStripSpacePointCalibrationDetailsDerived result{}; |
| 27 | + result.innerCrossOuterHalfVector = stdArrayCross(ihv, ohv); |
| 28 | + result.innerToOuterSeparationCrossOuterHalfVector = stdArrayCross(iosv, ohv); |
| 29 | + result.innerToOuterSeparationCrossInnerHalfVector = stdArrayCross(iosv, ihv); |
| 30 | + result.outerCenter = oc; |
| 31 | + result.outerHalfVector = ohv; |
| 32 | + return result; |
| 33 | +} |
| 34 | + |
| 35 | +inline OuterStripSpacePointCalibrationDetailsDerived |
| 36 | +deriveOuterStripSpacePointCalibrationDetails( |
| 37 | + const OuterStripSpacePointCalibrationDetails& sp) { |
| 38 | + return deriveOuterStripSpacePointCalibrationDetails( |
| 39 | + sp.innerHalfVector, sp.outerHalfVector, sp.innerToOuterSeparation, |
| 40 | + sp.outerCenter); |
| 41 | +} |
| 42 | + |
| 43 | +inline bool calibrateOuterStripSpacePoint( |
| 44 | + const std::array<float, 3>& direction, |
| 45 | + const std::array<float, 3>& ihvCrossOhv, |
| 46 | + const std::array<float, 3>& iosvCrossOhv, |
| 47 | + const std::array<float, 3>& iosvCrossIhv, const std::array<float, 3>& oc, |
| 48 | + const std::array<float, 3>& ohv, std::array<float, 3>& calibrated, |
| 49 | + const float tolerance) { |
| 50 | + // scale = innerStripHalfVector dot (outerStripHalfVector cross direction) |
| 51 | + const float scale = stdArrayDot(direction, ihvCrossOhv); |
| 52 | + |
| 53 | + // sInner = innerToOuterSeparationVector dot (outerStripHalfVector cross |
| 54 | + // direction) Check if direction is inside the inner detector element |
| 55 | + const float sInner = stdArrayDot(direction, iosvCrossOhv); |
| 56 | + if (std::abs(sInner) > std::abs(scale) * tolerance) { |
| 57 | + return false; |
| 58 | + } |
| 59 | + |
| 60 | + // sOuter = innerToOuterSeparationVector dot (innerStripHalfVector cross |
| 61 | + // direction) Check if direction is inside the outer detector element |
| 62 | + const float sOuter = stdArrayDot(direction, iosvCrossIhv); |
| 63 | + if (std::abs(sOuter) > std::abs(scale) * tolerance) { |
| 64 | + return false; |
| 65 | + } |
| 66 | + |
| 67 | + // Corrected position using the outer strip center and direction |
| 68 | + const float sOuterNorm = sOuter / scale; |
| 69 | + calibrated = stdArrayAddScaled(oc, ohv, sOuterNorm); |
| 70 | + return true; |
| 71 | +} |
| 72 | + |
| 73 | +inline bool calibrateOuterStripSpacePoint( |
| 74 | + const std::array<float, 3>& direction, |
| 75 | + const OuterStripSpacePointCalibrationDetailsDerived& sp, |
| 76 | + std::array<float, 3>& calibrated, const float tolerance) { |
| 77 | + return detail::calibrateOuterStripSpacePoint( |
| 78 | + direction, sp.innerCrossOuterHalfVector, |
| 79 | + sp.innerToOuterSeparationCrossOuterHalfVector, |
| 80 | + sp.innerToOuterSeparationCrossInnerHalfVector, sp.outerCenter, |
| 81 | + sp.outerHalfVector, calibrated, tolerance); |
| 82 | +} |
| 83 | + |
| 84 | +} // namespace Acts::detail |
0 commit comments