Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ScalingCalibrator.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ScalingCalibrator.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2023 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 
21 
22 #include <algorithm>
23 #include <array>
24 #include <bitset>
25 #include <cassert>
26 #include <cstring>
27 #include <filesystem>
28 #include <map>
29 #include <regex>
30 #include <stdexcept>
31 #include <string>
32 #include <type_traits>
33 #include <utility>
34 #include <variant>
35 #include <vector>
36 
37 #include <TCollection.h>
38 #include <TFile.h>
39 #include <TH2.h>
40 #include <TKey.h>
41 #include <TList.h>
42 #include <TString.h>
43 
44 namespace Acts {
45 class VectorMultiTrajectory;
46 } // namespace Acts
47 
48 namespace detail {
49 
50 std::pair<Acts::GeometryIdentifier, std::string> parseMapKey(
51  const std::string& mapkey) {
52  std::regex reg("^map_([0-9]+)-([0-9]+)-([0-9]+)_([xy]_.*)$");
53  std::smatch matches;
54 
55  if (std::regex_search(mapkey, matches, reg) && matches.size() == 5) {
56  size_t vol = std::stoull(matches[1].str());
57  size_t lyr = std::stoull(matches[2].str());
58  size_t mod = std::stoull(matches[3].str());
59 
61  geoId.setVolume(vol);
62  geoId.setLayer(lyr);
63  geoId.setSensitive(mod);
64 
65  std::string var(matches[4].str());
66 
67  return std::make_pair(geoId, var);
68  } else {
69  throw std::runtime_error("Invalid map key: " + mapkey);
70  }
71 }
72 
73 std::map<Acts::GeometryIdentifier, ActsExamples::ScalingCalibrator::MapTuple>
75  std::map<Acts::GeometryIdentifier, ActsExamples::ScalingCalibrator::MapTuple>
76  maps;
77 
78  TFile ifile(path.c_str(), "READ");
79  if (ifile.IsZombie()) {
80  throw std::runtime_error("Unable to open TFile: " + path.string());
81  }
82 
83  TList* lst = ifile.GetListOfKeys();
84  assert(lst != nullptr);
85 
86  for (auto it = lst->begin(); it != lst->end(); ++it) {
87  TKey* key = static_cast<TKey*>(*it);
88  if (std::strcmp(key->GetClassName(), "TH2D") == 0) {
89  auto [geoId, var] = parseMapKey(key->GetName());
90 
91  TH2D hist;
92  key->Read(&hist);
93 
94  if (var == "x_offset") {
95  maps[geoId].x_offset = hist;
96  } else if (var == "x_scale") {
97  maps[geoId].x_scale = hist;
98  } else if (var == "y_offset") {
99  maps[geoId].y_offset = hist;
100  } else if (var == "y_scale") {
101  maps[geoId].y_scale = hist;
102  } else {
103  throw std::runtime_error("Unrecognized var: " + var);
104  }
105  }
106  }
107  return maps;
108 }
109 
110 std::bitset<3> readMask(const std::filesystem::path& path) {
111  TFile ifile(path.c_str(), "READ");
112  if (ifile.IsZombie()) {
113  throw std::runtime_error("Unable to open TFile: " + path.string());
114  }
115 
116  TString* tstr = ifile.Get<TString>("v_mask");
117  if (tstr == nullptr) {
118  throw std::runtime_error("Unable to read mask");
119  }
120 
121  return std::bitset<3>(std::string(*tstr));
122 }
123 
124 } // namespace detail
125 
128  : m_calib_maps{::detail::readMaps(path)},
129  m_mask{::detail::readMask(path)} {}
130 
132  const MeasurementContainer& measurements, const ClusterContainer* clusters,
133  const Acts::GeometryContext& /*gctx*/,
134  const Acts::CalibrationContext& /*cctx*/,
135  const Acts::SourceLink& sourceLink,
137  trackState.setUncalibratedSourceLink(sourceLink);
138  const IndexSourceLink& idxSourceLink = sourceLink.get<IndexSourceLink>();
139 
140  assert((idxSourceLink.index() < measurements.size()) and
141  "Source link index is outside the container bounds");
142 
143  auto geoId = trackState.referenceSurface().geometryId();
145  mgid.setVolume(geoId.volume() *
146  static_cast<Acts::GeometryIdentifier::Value>(m_mask[2]));
147  mgid.setLayer(geoId.layer() *
148  static_cast<Acts::GeometryIdentifier::Value>(m_mask[1]));
149  mgid.setSensitive(geoId.sensitive() *
150  static_cast<Acts::GeometryIdentifier::Value>(m_mask[0]));
151  const Cluster& cl = clusters->at(idxSourceLink.index());
152  ConstantTuple ct = m_calib_maps.at(mgid).at(cl.sizeLoc0, cl.sizeLoc1);
153 
154  std::visit(
155  [&](const auto& meas) {
156  auto E = meas.expander();
157  auto P = meas.projector();
158 
159  Acts::ActsVector<Acts::eBoundSize> fpar = E * meas.parameters();
160 
162  E * meas.covariance() * E.transpose();
163 
164  fpar[Acts::eBoundLoc0] += ct.x_offset;
165  fpar[Acts::eBoundLoc1] += ct.y_offset;
166  fcov(Acts::eBoundLoc0, Acts::eBoundLoc0) *= ct.x_scale;
167  fcov(Acts::eBoundLoc1, Acts::eBoundLoc1) *= ct.y_scale;
168 
169  constexpr size_t kSize =
171  std::array<Acts::BoundIndices, kSize> indices = meas.indices();
172  Acts::ActsVector<kSize> cpar = P * fpar;
173  Acts::ActsSquareMatrix<kSize> ccov = P * fcov * P.transpose();
174 
176  Acts::SourceLink{idxSourceLink}, indices, cpar, ccov);
177 
178  trackState.allocateCalibrated(cmeas.size());
179  trackState.setCalibrated(cmeas);
180  },
181  (measurements)[idxSourceLink.index()]);
182 }