Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:46

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 #pragma once
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/Logger.hpp"
0016 #include "ActsExamples/EventData/Index.hpp"
0017 #include "ActsExamples/EventData/SimHit.hpp"
0018 #include "ActsExamples/Utilities/Range.hpp"
0019 
0020 #include <tuple>
0021 
0022 namespace ActsExamples {
0023 
0024 /// A range within a hit-simhits map.
0025 using HitSimHitsRange = Range<IndexMultimap<Index>::const_iterator>;
0026 
0027 /// Create (average) truth representation for selected simulated hits.
0028 ///
0029 /// @param gCtx The geometry context for this
0030 /// @param surface The reference surface of the measurement
0031 /// @param simHits The simulated hits container
0032 /// @param hitSimHitsRange Selection of simulated hits from the container
0033 /// @return a local position, a 4D global position, a direction
0034 ///
0035 /// If more than one simulated hit is selected, the average truth information is
0036 /// returned.
0037 inline std::tuple<Acts::Vector2, Acts::Vector4, Acts::Vector3> averageSimHits(
0038     const Acts::GeometryContext& gCtx, const Acts::Surface& surface,
0039     const SimHitContainer& simHits, const HitSimHitsRange& hitSimHitsRange,
0040     const Acts::Logger& logger) {
0041   using namespace Acts::UnitLiterals;
0042 
0043   Acts::Vector2 avgLocal = Acts::Vector2::Zero();
0044   Acts::Vector4 avgPos4 = Acts::Vector4::Zero();
0045   Acts::Vector3 avgDir = Acts::Vector3::Zero();
0046 
0047   std::size_t n = 0u;
0048   for (auto [_, simHitIdx] : hitSimHitsRange) {
0049     n += 1u;
0050 
0051     // we assume that the indices are within valid ranges so we do not need to
0052     // check their validity again.
0053     const auto& simHit = *simHits.nth(simHitIdx);
0054 
0055     // We use the thickness of the detector element as tolerance, because Geant4
0056     // treats the Surfaces as volumes and thus it is not ensured, that each hit
0057     // lies exactly on the Acts::Surface
0058     const auto tolerance =
0059         surface.associatedDetectorElement() != nullptr
0060             ? surface.associatedDetectorElement()->thickness()
0061             : Acts::s_onSurfaceTolerance;
0062 
0063     // transforming first to local positions and average that ensures that the
0064     // averaged position is still on the surface. the averaged global position
0065     // might not be on the surface anymore.
0066     auto result = surface.globalToLocal(gCtx, simHit.position(),
0067                                         simHit.direction(), tolerance);
0068     if (result.ok()) {
0069       avgLocal += result.value();
0070     } else {
0071       ACTS_WARNING("While averaging simhit, hit "
0072                    << simHitIdx << " is not on the corresponding surface "
0073                    << surface.geometryId() << "; use [0,0] as local position");
0074     }
0075     // global position should already be at the intersection. no need to perform
0076     // an additional intersection call.
0077     avgPos4 += simHit.fourPosition();
0078     avgDir += simHit.direction();
0079   }
0080 
0081   // only need to average if there are at least two inputs
0082   if (2u <= n) {
0083     double scale = 1.0 / n;
0084     avgLocal *= scale;
0085     avgPos4 *= scale;
0086     avgDir.normalize();
0087   }
0088 
0089   return {avgLocal, avgPos4, avgDir};
0090 }
0091 
0092 }  // namespace ActsExamples