Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ExternalAlignmentDecorator.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ExternalAlignmentDecorator.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
17 
18 #include <cassert>
19 #include <ostream>
20 #include <thread>
21 #include <utility>
22 
25  std::unique_ptr<const Acts::Logger> logger)
26  : m_cfg(cfg), m_logger(std::move(logger)) {
27  if (m_cfg.trackingGeometry != nullptr) {
28  // parse and populate
30  }
31 }
32 
35  AlgorithmContext& context) {
36  // Iov map access needs to be synchronized
37  std::lock_guard lock{m_iovMutex};
38 
39  // In which iov batch are we?
40  unsigned int iov = context.eventNumber / m_cfg.iovSize;
41  ACTS_VERBOSE("IOV handling in thread " << std::this_thread::get_id() << ".");
42  ACTS_VERBOSE("IOV resolved to " << iov << " - from event "
43  << context.eventNumber << ".");
44 
45  m_eventsSeen++;
46 
47  if (m_cfg.randomNumberSvc != nullptr) {
48  if (auto it = m_activeIovs.find(iov); it != m_activeIovs.end()) {
49  // Iov is already present, update last accessed
50  it->second->lastAccessed = m_eventsSeen;
51  context.geoContext =
53  } else {
54  // Iov is not present yet, create it
55  auto alignmentStore =
56  std::make_unique<ExternallyAlignedDetectorElement::AlignmentStore>();
57  alignmentStore->lastAccessed = m_eventsSeen;
58 
59  ACTS_VERBOSE("New IOV " << iov << " detected at event "
60  << context.eventNumber
61  << ", emulate new alignment.");
62 
63  // Create an algorithm local random number generator
64  RandomEngine rng = m_cfg.randomNumberSvc->spawnGenerator(context);
65 
66  alignmentStore->transforms = m_nominalStore; // copy nominal alignment
67  for (auto& tForm : alignmentStore->transforms) {
68  // Multiply alignment in place
69  applyTransform(tForm, m_cfg, rng, iov);
70  }
71 
72  auto [insertIterator, inserted] =
73  m_activeIovs.emplace(iov, std::move(alignmentStore));
74  assert(inserted && "Expected IOV to be created in map, but wasn't");
75 
76  // make context from iov pointer, address should be stable
77  context.geoContext =
78  ExternallyAlignedDetectorElement::ContextType{insertIterator->second};
79  }
80  }
81 
82  // Garbage collection
83  if (m_cfg.doGarbageCollection) {
84  for (auto it = m_activeIovs.begin(); it != m_activeIovs.end();) {
85  auto& status = it->second;
86  if (m_eventsSeen - status->lastAccessed > m_cfg.flushSize) {
87  ACTS_DEBUG("IOV " << iov << " has not been accessed in the last "
88  << m_cfg.flushSize << " events, clearing");
89  it = m_activeIovs.erase(it);
90  } else {
91  it++;
92  }
93  }
94  }
95 
96  return ProcessCode::SUCCESS;
97 }
98 
101  // Double-visit - first count
102  size_t nTransforms = 0;
103  tGeometry.visitSurfaces([&nTransforms](const auto*) { ++nTransforms; });
104 
105  Acts::GeometryContext nominalCtx{
107 
108  // Collect the surfacas into the nominal store
109  std::vector<Acts::Transform3> aStore(nTransforms,
110  Acts::Transform3::Identity());
111 
112  auto fillTransforms = [&aStore, &nominalCtx](const auto* surface) -> void {
113  auto alignableElement =
114  dynamic_cast<const ExternallyAlignedDetectorElement*>(
115  surface->associatedDetectorElement());
116  aStore[alignableElement->identifier()] = surface->transform(nominalCtx);
117  };
118 
119  tGeometry.visitSurfaces(fillTransforms);
120  m_nominalStore = std::move(aStore);
121 }