File indexing completed on 2025-08-06 08:10:41
0001
0002
0003
0004
0005
0006
0007
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
0029 parseGeometry(*m_cfg.trackingGeometry.get());
0030 }
0031 }
0032
0033 ActsExamples::ProcessCode
0034 ActsExamples::Contextual::ExternalAlignmentDecorator::decorate(
0035 AlgorithmContext& context) {
0036
0037 std::lock_guard lock{m_iovMutex};
0038
0039
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
0050 it->second->lastAccessed = m_eventsSeen;
0051 context.geoContext =
0052 ExternallyAlignedDetectorElement::ContextType{it->second};
0053 } else {
0054
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
0064 RandomEngine rng = m_cfg.randomNumberSvc->spawnGenerator(context);
0065
0066 alignmentStore->transforms = m_nominalStore;
0067 for (auto& tForm : alignmentStore->transforms) {
0068
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
0077 context.geoContext =
0078 ExternallyAlignedDetectorElement::ContextType{insertIterator->second};
0079 }
0080 }
0081
0082
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
0102 std::size_t nTransforms = 0;
0103 tGeometry.visitSurfaces([&nTransforms](const auto*) { ++nTransforms; });
0104
0105 Acts::GeometryContext nominalCtx{
0106 ExternallyAlignedDetectorElement::ContextType{}};
0107
0108
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 }