Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:10:41

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 #include "ActsExamples/ContextualDetector/ExternalAlignmentDecorator.hpp"
0010 
0011 #include "Acts/Geometry/GeometryContext.hpp"
0012 #include "Acts/Geometry/TrackingGeometry.hpp"
0013 #include "Acts/Surfaces/SurfaceArray.hpp"
0014 #include "ActsExamples/ContextualDetector/ExternallyAlignedDetectorElement.hpp"
0015 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0016 #include "ActsExamples/Framework/RandomNumbers.hpp"
0017 
0018 #include <cassert>
0019 #include <ostream>
0020 #include <thread>
0021 #include <utility>
0022 
0023 ActsExamples::Contextual::ExternalAlignmentDecorator::
0024     ExternalAlignmentDecorator(const Config& cfg,
0025                                std::unique_ptr<const Acts::Logger> logger)
0026     : m_cfg(cfg), m_logger(std::move(logger)) {
0027   if (m_cfg.trackingGeometry != nullptr) {
0028     // parse and populate
0029     parseGeometry(*m_cfg.trackingGeometry.get());
0030   }
0031 }
0032 
0033 ActsExamples::ProcessCode
0034 ActsExamples::Contextual::ExternalAlignmentDecorator::decorate(
0035     AlgorithmContext& context) {
0036   // Iov map access needs to be synchronized
0037   std::lock_guard lock{m_iovMutex};
0038 
0039   // In which iov batch are we?
0040   unsigned int iov = context.eventNumber / m_cfg.iovSize;
0041   ACTS_VERBOSE("IOV handling in thread " << std::this_thread::get_id() << ".");
0042   ACTS_VERBOSE("IOV resolved to " << iov << " - from event "
0043                                   << context.eventNumber << ".");
0044 
0045   m_eventsSeen++;
0046 
0047   if (m_cfg.randomNumberSvc != nullptr) {
0048     if (auto it = m_activeIovs.find(iov); it != m_activeIovs.end()) {
0049       // Iov is already present, update last accessed
0050       it->second->lastAccessed = m_eventsSeen;
0051       context.geoContext =
0052           ExternallyAlignedDetectorElement::ContextType{it->second};
0053     } else {
0054       // Iov is not present yet, create it
0055       auto alignmentStore =
0056           std::make_unique<ExternallyAlignedDetectorElement::AlignmentStore>();
0057       alignmentStore->lastAccessed = m_eventsSeen;
0058 
0059       ACTS_VERBOSE("New IOV " << iov << " detected at event "
0060                               << context.eventNumber
0061                               << ", emulate new alignment.");
0062 
0063       // Create an algorithm local random number generator
0064       RandomEngine rng = m_cfg.randomNumberSvc->spawnGenerator(context);
0065 
0066       alignmentStore->transforms = m_nominalStore;  // copy nominal alignment
0067       for (auto& tForm : alignmentStore->transforms) {
0068         // Multiply alignment in place
0069         applyTransform(tForm, m_cfg, rng, iov);
0070       }
0071 
0072       auto [insertIterator, inserted] =
0073           m_activeIovs.emplace(iov, std::move(alignmentStore));
0074       assert(inserted && "Expected IOV to be created in map, but wasn't");
0075 
0076       // make context from iov pointer, address should be stable
0077       context.geoContext =
0078           ExternallyAlignedDetectorElement::ContextType{insertIterator->second};
0079     }
0080   }
0081 
0082   // Garbage collection
0083   if (m_cfg.doGarbageCollection) {
0084     for (auto it = m_activeIovs.begin(); it != m_activeIovs.end();) {
0085       auto& status = it->second;
0086       if (m_eventsSeen - status->lastAccessed > m_cfg.flushSize) {
0087         ACTS_DEBUG("IOV " << iov << " has not been accessed in the last "
0088                           << m_cfg.flushSize << " events, clearing");
0089         it = m_activeIovs.erase(it);
0090       } else {
0091         it++;
0092       }
0093     }
0094   }
0095 
0096   return ProcessCode::SUCCESS;
0097 }
0098 
0099 void ActsExamples::Contextual::ExternalAlignmentDecorator::parseGeometry(
0100     const Acts::TrackingGeometry& tGeometry) {
0101   // Double-visit - first count
0102   std::size_t nTransforms = 0;
0103   tGeometry.visitSurfaces([&nTransforms](const auto*) { ++nTransforms; });
0104 
0105   Acts::GeometryContext nominalCtx{
0106       ExternallyAlignedDetectorElement::ContextType{}};
0107 
0108   // Collect the surfacas into the nominal store
0109   std::vector<Acts::Transform3> aStore(nTransforms,
0110                                        Acts::Transform3::Identity());
0111 
0112   auto fillTransforms = [&aStore, &nominalCtx](const auto* surface) -> void {
0113     auto alignableElement =
0114         dynamic_cast<const ExternallyAlignedDetectorElement*>(
0115             surface->associatedDetectorElement());
0116     aStore[alignableElement->identifier()] = surface->transform(nominalCtx);
0117   };
0118 
0119   tGeometry.visitSurfaces(fillTransforms);
0120   m_nominalStore = std::move(aStore);
0121 }