Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-18 09:11:28

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2019 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/GeometryContext.hpp"
0013 #include "Acts/Geometry/GeometryIdentifier.hpp"
0014 #include "Acts/Plugins/Identification/IdentifiedDetectorElement.hpp"
0015 #include "Acts/Plugins/Identification/Identifier.hpp"
0016 #include "Acts/Surfaces/Surface.hpp"
0017 #include "ActsExamples/GenericDetector/GenericDetectorElement.hpp"
0018 
0019 #include <iostream>
0020 #include <memory>
0021 #include <mutex>
0022 #include <unordered_map>
0023 
0024 namespace ActsExamples::Contextual {
0025 
0026 /// @class InternallyAlignedDetectorElement extends GenericDetectorElement
0027 ///
0028 /// This is a lightweight type of detector element,
0029 /// it simply implements the base class.
0030 ///
0031 /// The AlignedDetectorElement demonstrates how a GeometryContext
0032 /// can be used if it carries an interval of validity concept
0033 ///
0034 /// The nominal transform is only used to once create the alignment
0035 /// store and then in a contextual call the actual detector element
0036 /// position is taken internal multi component store - the latter
0037 /// has to be filled though from an external source
0038 class InternallyAlignedDetectorElement
0039     : public Generic::GenericDetectorElement {
0040  public:
0041   struct ContextType {
0042     /// The current interval of validity
0043     unsigned int iov = 0;
0044     bool nominal = false;
0045   };
0046 
0047   // Inherit constructor
0048   using Generic::GenericDetectorElement::GenericDetectorElement;
0049 
0050   /// Return local to global transform associated with this identifier
0051   ///
0052   /// @param gctx The current geometry context object, e.g. alignment
0053   ///
0054   /// @note this is called from the surface().transform(gctx)
0055   const Acts::Transform3& transform(
0056       const Acts::GeometryContext& gctx) const override;
0057 
0058   /// Return the nominal local to global transform
0059   ///
0060   /// @note the geometry context will hereby be ignored
0061   const Acts::Transform3& nominalTransform(
0062       const Acts::GeometryContext& gctx) const;
0063 
0064   /// Return local to global transform associated with this identifier
0065   ///
0066   /// @param alignedTransform is a new transform
0067   /// @param iov is the batch for which it is meant
0068   void addAlignedTransform(const Acts::Transform3& alignedTransform,
0069                            unsigned int iov);
0070 
0071   void clearAlignedTransform(unsigned int iov);
0072 
0073  private:
0074   std::unordered_map<unsigned int, Acts::Transform3> m_alignedTransforms;
0075   mutable std::mutex m_alignmentMutex;
0076 };
0077 
0078 inline const Acts::Transform3& InternallyAlignedDetectorElement::transform(
0079     const Acts::GeometryContext& gctx) const {
0080   if (!gctx.hasValue()) {
0081     // Return the standard transform if geo context is empty
0082     return nominalTransform(gctx);
0083   }
0084   const auto& alignContext = gctx.get<ContextType&>();
0085 
0086   std::lock_guard lock{m_alignmentMutex};
0087   if (alignContext.nominal) {
0088     // nominal alignment
0089     return nominalTransform(gctx);
0090   }
0091   auto aTransform = m_alignedTransforms.find(alignContext.iov);
0092   if (aTransform == m_alignedTransforms.end()) {
0093     throw std::runtime_error{
0094         "Aligned transform for IOV " + std::to_string(alignContext.iov) +
0095         " not found. This can happen if the garbage collection runs too "
0096         "early (--align-flushsize too low)"};
0097   }
0098   return aTransform->second;
0099 }
0100 
0101 inline const Acts::Transform3&
0102 InternallyAlignedDetectorElement::nominalTransform(
0103     const Acts::GeometryContext& gctx) const {
0104   return GenericDetectorElement::transform(gctx);
0105 }
0106 
0107 inline void InternallyAlignedDetectorElement::addAlignedTransform(
0108     const Acts::Transform3& alignedTransform, unsigned int iov) {
0109   std::lock_guard lock{m_alignmentMutex};
0110   m_alignedTransforms[iov] = alignedTransform;
0111 }
0112 
0113 inline void InternallyAlignedDetectorElement::clearAlignedTransform(
0114     unsigned int iov) {
0115   std::lock_guard lock{m_alignmentMutex};
0116   if (auto it = m_alignedTransforms.find(iov);
0117       it != m_alignedTransforms.end()) {
0118     m_alignedTransforms.erase(it);
0119   }
0120 }
0121 
0122 }  // namespace ActsExamples::Contextual