File indexing completed on 2025-01-31 09:16:52
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 "ActsExamples/ContextualDetector/ExternallyAlignedDetectorElement.hpp"
0014 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0015 #include "ActsExamples/Framework/RandomNumbers.hpp"
0016
0017 #include <cassert>
0018 #include <ostream>
0019 #include <thread>
0020 #include <utility>
0021
0022 namespace ActsExamples {
0023
0024 ExternalAlignmentDecorator::ExternalAlignmentDecorator(
0025 const Config& cfg, 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 ProcessCode ExternalAlignmentDecorator::decorate(AlgorithmContext& context) {
0034
0035 std::lock_guard lock{m_iovMutex};
0036
0037
0038 unsigned int iov = context.eventNumber / m_cfg.iovSize;
0039 ACTS_VERBOSE("IOV handling in thread " << std::this_thread::get_id() << ".");
0040 ACTS_VERBOSE("IOV resolved to " << iov << " - from event "
0041 << context.eventNumber << ".");
0042
0043 m_eventsSeen++;
0044
0045 if (m_cfg.randomNumberSvc != nullptr) {
0046 if (auto it = m_activeIovs.find(iov); it != m_activeIovs.end()) {
0047
0048 it->second->lastAccessed = m_eventsSeen;
0049 context.geoContext =
0050 ExternallyAlignedDetectorElement::ContextType{it->second};
0051 } else {
0052
0053 auto alignmentStore =
0054 std::make_unique<ExternallyAlignedDetectorElement::AlignmentStore>();
0055 alignmentStore->lastAccessed = m_eventsSeen;
0056
0057 ACTS_VERBOSE("New IOV " << iov << " detected at event "
0058 << context.eventNumber
0059 << ", emulate new alignment.");
0060
0061
0062 RandomEngine rng = m_cfg.randomNumberSvc->spawnGenerator(context);
0063
0064 alignmentStore->transforms = m_nominalStore;
0065 for (auto& tForm : alignmentStore->transforms) {
0066
0067 applyTransform(tForm, m_cfg, rng, iov);
0068 }
0069
0070 auto [insertIterator, inserted] =
0071 m_activeIovs.emplace(iov, std::move(alignmentStore));
0072 assert(inserted && "Expected IOV to be created in map, but wasn't");
0073
0074
0075 context.geoContext =
0076 ExternallyAlignedDetectorElement::ContextType{insertIterator->second};
0077 }
0078 }
0079
0080
0081 if (m_cfg.doGarbageCollection) {
0082 for (auto it = m_activeIovs.begin(); it != m_activeIovs.end();) {
0083 auto& status = it->second;
0084 if (m_eventsSeen - status->lastAccessed > m_cfg.flushSize) {
0085 ACTS_DEBUG("IOV " << iov << " has not been accessed in the last "
0086 << m_cfg.flushSize << " events, clearing");
0087 it = m_activeIovs.erase(it);
0088 } else {
0089 it++;
0090 }
0091 }
0092 }
0093
0094 return ProcessCode::SUCCESS;
0095 }
0096
0097 void ExternalAlignmentDecorator::parseGeometry(
0098 const Acts::TrackingGeometry& tGeometry) {
0099
0100 std::size_t nTransforms = 0;
0101 tGeometry.visitSurfaces([&nTransforms](const auto*) { ++nTransforms; });
0102
0103 Acts::GeometryContext nominalCtx{
0104 ExternallyAlignedDetectorElement::ContextType{}};
0105
0106
0107 std::vector<Acts::Transform3> aStore(nTransforms,
0108 Acts::Transform3::Identity());
0109
0110 auto fillTransforms = [&aStore, &nominalCtx](const auto* surface) -> void {
0111 if (surface == nullptr) {
0112 throw std::invalid_argument("Surface is nullptr.");
0113 }
0114 auto alignableElement =
0115 dynamic_cast<const ExternallyAlignedDetectorElement*>(
0116 surface->associatedDetectorElement());
0117 if (alignableElement == nullptr) {
0118 throw std::invalid_argument("Surface is not alignable");
0119 }
0120 aStore[alignableElement->identifier()] = surface->transform(nominalCtx);
0121 };
0122
0123 tGeometry.visitSurfaces(fillTransforms);
0124 m_nominalStore = std::move(aStore);
0125 }
0126
0127 }