Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MeasurementReaderWriterTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MeasurementReaderWriterTests.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 
9 #include <boost/test/unit_test.hpp>
10 
15 #include "Acts/Utilities/Zip.hpp"
22 
23 #include <fstream>
24 #include <iostream>
25 #include <random>
26 
27 using namespace ActsExamples;
28 using namespace Acts::Test;
29 
30 BOOST_AUTO_TEST_CASE(CsvMeasurementRoundTrip) {
31  IndexSourceLinkContainer sourceLinksOriginal;
32  MeasurementContainer measOriginal;
33  ClusterContainer clusterOriginal;
34  IndexMultimap<Index> mapOriginal;
35 
37  // Create some dummy data //
39  const std::size_t nMeasurements = 3;
40  Acts::GeometryIdentifier someGeoId{298453};
41 
42  std::mt19937 gen(23);
43  std::uniform_int_distribution<unsigned> disti(1, 10);
44  std::uniform_real_distribution<double> distf(0.0, 1.0);
45 
46  for (auto i = 0ul; i < nMeasurements; ++i) {
47  IndexSourceLink sl(someGeoId, static_cast<Index>(i));
48  sourceLinksOriginal.insert(sl);
49 
50  Acts::Vector2 p = Acts::Vector2::Random();
51  Acts::SquareMatrix2 c = Acts::SquareMatrix2::Random();
52 
53  // NOTE this fails:
54  // auto m = Acts::makeMeasurement(sl, p, c, eBoundLoc0, eBoundTime)
55  // because we don't support non-consecutive parameters here for now
58 
59  measOriginal.push_back(m);
60 
62 
63  using Bin2D = ActsFatras::Channelizer::Bin2D;
65 
66  // We have two cluster shapes which are displaced randomly
67  const auto o = disti(gen);
68  cl.channels.emplace_back(
69  Bin2D{o + 0, o + 0},
70  Seg2D{Acts::Vector2::Random(), Acts::Vector2::Random()}, distf(gen));
71  cl.channels.emplace_back(
72  Bin2D{o + 0, o + 1},
73  Seg2D{Acts::Vector2::Random(), Acts::Vector2::Random()}, distf(gen));
74  if (distf(gen) < 0.5) {
75  cl.channels.emplace_back(
76  Bin2D{o + 0, o + 2},
77  Seg2D{Acts::Vector2::Random(), Acts::Vector2::Random()}, distf(gen));
78  cl.sizeLoc0 = 1;
79  cl.sizeLoc1 = 3;
80  } else {
81  cl.channels.emplace_back(
82  Bin2D{o + 1, o + 0},
83  Seg2D{Acts::Vector2::Random(), Acts::Vector2::Random()}, distf(gen));
84  cl.sizeLoc0 = 2;
85  cl.sizeLoc1 = 2;
86  }
87 
88  clusterOriginal.push_back(cl);
89 
90  // Just generate some random hitid
91  mapOriginal.insert(std::pair<Index, Index>{i, disti(gen)});
92  }
93 
95  // Write //
97  CsvMeasurementWriter::Config writerConfig;
98  writerConfig.inputClusters = "clusters";
99  writerConfig.inputMeasurements = "meas";
100  writerConfig.inputMeasurementSimHitsMap = "map";
101  writerConfig.outputDir = "";
102 
104 
105  auto writeTool =
107  .add(writerConfig.inputMeasurements, measOriginal)
108  .add(writerConfig.inputClusters, clusterOriginal)
109  .add(writerConfig.inputMeasurementSimHitsMap, mapOriginal);
110 
111  writeTool.write(writer);
112 
114  // Write & Read //
116  CsvMeasurementReader::Config readerConfig;
117  readerConfig.inputDir = writerConfig.outputDir;
118  readerConfig.outputMeasurements = writerConfig.inputMeasurements;
119  readerConfig.outputMeasurementSimHitsMap =
120  writerConfig.inputMeasurementSimHitsMap;
121  readerConfig.outputClusters = writerConfig.inputClusters;
122  readerConfig.outputSourceLinks = "sourcelinks";
123 
125 
126  auto readTool =
127  writeTool.add(readerConfig.outputSourceLinks, sourceLinksOriginal);
128 
129  const auto [measRead, clusterRead, mapRead, sourceLinksRead] =
130  readTool.read(reader);
131 
133  // Check //
135  auto checkMeasurementClose = [](const auto &m1, const auto &m2) {
136  constexpr auto SizeA = std::decay_t<decltype(m1)>::size();
137  constexpr auto SizeB = std::decay_t<decltype(m2)>::size();
138  if constexpr (SizeA == SizeB) {
139  CHECK_CLOSE_REL(m1.parameters(), m2.parameters(), 1e-4);
140  }
141  };
142 
143  static_assert(
144  std::is_same_v<std::decay_t<decltype(measRead)>, decltype(measOriginal)>);
145  BOOST_REQUIRE(measRead.size() == measOriginal.size());
146  for (const auto &[a, b] : Acts::zip(measRead, measOriginal)) {
147  std::visit(checkMeasurementClose, a, b);
148  }
149 
150  static_assert(std::is_same_v<std::decay_t<decltype(clusterRead)>,
151  decltype(clusterOriginal)>);
152  BOOST_REQUIRE(clusterRead.size() == clusterOriginal.size());
153  for (auto [a, b] : Acts::zip(clusterRead, clusterOriginal)) {
154  BOOST_REQUIRE(a.sizeLoc0 == b.sizeLoc0);
155  BOOST_REQUIRE(a.sizeLoc1 == b.sizeLoc1);
156 
157  for (const auto &ca : a.channels) {
158  auto match = [&](const auto &cb) {
159  return ca.bin == cb.bin &&
160  std::abs(ca.activation - cb.activation) < 1.e-4;
161  };
162 
163  BOOST_CHECK(std::any_of(b.channels.begin(), b.channels.end(), match));
164  }
165  }
166 
167  static_assert(
168  std::is_same_v<std::decay_t<decltype(mapRead)>, decltype(mapOriginal)>);
169  BOOST_REQUIRE(mapRead.size() == mapOriginal.size());
170  for (const auto &[a, b] : Acts::zip(mapRead, mapOriginal)) {
171  BOOST_REQUIRE(a == b);
172  }
173 
174  static_assert(std::is_same_v<std::decay_t<decltype(sourceLinksRead)>,
175  decltype(sourceLinksOriginal)>);
176  BOOST_REQUIRE(sourceLinksRead.size() == sourceLinksOriginal.size());
177  for (const auto &[a, b] : Acts::zip(sourceLinksRead, sourceLinksOriginal)) {
178  BOOST_REQUIRE(a.geometryId() == b.geometryId());
179  BOOST_REQUIRE(a.index() == b.index());
180  }
181 }