Project
Loading...
Searching...
No Matches
testGeometryTransformer.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#define BOOST_TEST_MODULE Test MCHSimulation GeometryTransformer
16#define BOOST_TEST_DYN_LINK
17
18#include <boost/test/unit_test.hpp>
19
23#include "TGeoManager.h"
24#include "boost/format.hpp"
25#include <boost/test/data/test_case.hpp>
26#include <fstream>
27#include <iomanip>
28#include <iostream>
29#include <fmt/format.h>
30#include <random>
31
32namespace bdata = boost::unit_test::data;
33
34BOOST_TEST_DONT_PRINT_LOG_VALUE(o2::mch::geo::TransformationCreator)
35
36constexpr int ntrans{2};
37
39{
40 static std::vector<o2::mch::geo::TransformationCreator> vtrans;
41
42 BOOST_REQUIRE(boost::unit_test::framework::master_test_suite().argc == 2);
43
44 if (vtrans.empty()) {
45 if (!gGeoManager) {
48 }
49 BOOST_TEST_REQUIRE(boost::unit_test::framework::master_test_suite().argc == 2);
50 std::string jsonInput = boost::unit_test::framework::master_test_suite().argv[1];
51 std::ifstream in(jsonInput);
52 vtrans = {
55 }
56 return vtrans[i];
57}
58
59constexpr double rad2deg = 180.0 / 3.14159265358979323846;
60constexpr double deg2rad = 3.14159265358979323846 / 180.0;
61
62void dumpMat(gsl::span<double> m)
63{
64 std::cout << fmt::format(
65 "{:7.3f} {:7.3f} {:7.3f}\n"
66 "{:7.3f} {:7.3f} {:7.3f}\n"
67 "{:7.3f} {:7.3f} {:7.3f}\n",
68 m[0], m[1], m[2],
69 m[3], m[4], m[5],
70 m[6], m[7], m[8]);
71}
72
73BOOST_DATA_TEST_CASE(GetTransformationMustNotThrowForValidDetElemId, bdata::xrange(ntrans), tindex)
74{
75 for (auto detElemId : o2::mch::geo::allDeIds) {
76 BOOST_REQUIRE_NO_THROW((transformation(tindex))(detElemId));
77 }
78}
79
80BOOST_DATA_TEST_CASE(GetTransformationMustThrowForInvalidDetElemId, bdata::xrange(ntrans), tindex)
81{
82 const auto someInvalidDetElemIds = {99, 105, 1026};
83
84 for (auto detElemId : someInvalidDetElemIds) {
85 BOOST_CHECK_THROW((transformation(tindex)(detElemId)), std::runtime_error);
86 }
87}
88
89struct CoarseLocation {
90 bool isRight;
91 bool isTop;
92};
93
94constexpr CoarseLocation topRight{true, true};
95constexpr CoarseLocation topLeft{false, true};
96constexpr CoarseLocation bottomRight{true, false};
97constexpr CoarseLocation bottomLeft{false, false};
98
99std::string asString(const CoarseLocation& q)
100{
101 std::string s = q.isTop ? "TOP" : "BOTTOM";
102 s += q.isRight ? "RIGHT" : "LEFT";
103 return s;
104}
105
106bool operator==(const CoarseLocation& a, const CoarseLocation& b)
107{
108 return a.isRight == b.isRight && a.isTop == b.isTop;
109}
110
112{
113 auto t = transformation(detElemId);
114
115 o2::math_utils::Point3D<double> localTestPos{0.0, 0.0, 0.0}; // slat center
116
117 if (detElemId < 500) {
118 // in the rough ballpark of the center
119 // of the quadrants
120 localTestPos.SetXYZ(60, 60, 0);
121 }
122
123 // for slats around the middle (y closest to 0) we have to be a bit
124 // more precise, so take a given pad reference, chosen to be
125 // the most top right or most top left pad
126
127 switch (detElemId) {
128 case 500:
129 case 509:
130 localTestPos.SetXYZ(-72.50, 19.75, 0.0); // ds 107
131 break;
132 case 600:
133 case 609:
134 localTestPos.SetXYZ(-77.50, 19.75, 0.0); // ds 108
135 break;
136 case 700:
137 case 713:
138 case 800:
139 case 813:
140 case 900:
141 case 913:
142 case 1000:
143 case 1013:
144 localTestPos.SetXYZ(95.0, -19.75, 0); // ds 104
145 break;
146 }
148
149 t.LocalToMaster(localTestPos, master);
150 bool right = master.x() > 10.;
151 bool top = master.y() > -10.;
152
153 return CoarseLocation{right, top};
154}
155
156void setExpectation(int firstDeId, int lastDeId, CoarseLocation q, std::map<int, CoarseLocation>& expected)
157{
158 for (int deid = firstDeId; deid <= lastDeId; deid++) {
159 expected.emplace(deid, q);
160 }
161}
162
163BOOST_DATA_TEST_CASE(DetectionElementMustBeInTheRightCoarseLocation, bdata::xrange(ntrans), tindex)
164{
165 std::map<int, CoarseLocation> expected;
166
167 for (int i = 0; i < 4; i++) {
168 expected[100 + i * 100] = topRight;
169 expected[101 + i * 100] = topLeft;
170 expected[102 + i * 100] = bottomLeft;
171 expected[103 + i * 100] = bottomRight;
172 }
173
174 // note that by convention we consider slats in the middle to be "top"
175 for (int i = 0; i < 2; i++) {
176 setExpectation(500 + i * 100, 504 + i * 100, topRight, expected);
177 setExpectation(505 + i * 100, 509 + i * 100, topLeft, expected);
178 setExpectation(510 + i * 100, 513 + i * 100, bottomLeft, expected);
179 setExpectation(514 + i * 100, 517 + i * 100, bottomRight, expected);
180 }
181
182 for (int i = 0; i < 4; i++) {
183 setExpectation(700 + i * 100, 706 + i * 100, topRight, expected);
184 setExpectation(707 + i * 100, 713 + i * 100, topLeft, expected);
185 setExpectation(714 + i * 100, 719 + i * 100, bottomLeft, expected);
186 setExpectation(720 + i * 100, 725 + i * 100, bottomRight, expected);
187 }
188
189 for (auto detElemId : o2::mch::geo::allDeIds) {
190 if (expected.find(detElemId) == expected.end()) {
191 std::cout << "got no expectation for DE=" << detElemId << "\n";
192 return;
193 }
194 BOOST_TEST_INFO_SCOPE(fmt::format("DeId {}", detElemId));
196 };
197}
198
199BOOST_AUTO_TEST_CASE(Angle2Matrix2Angle)
200{
201 std::random_device rd;
202 std::mt19937 mt(rd());
203 std::vector<std::tuple<double, double, double>> testAngles;
204 int n{100};
205
206 testAngles.resize(n);
207 constexpr double pi = 3.14159265358979323846;
208 std::uniform_real_distribution<double> dist{-pi / 2.0, pi / 2.0};
209 std::uniform_real_distribution<double> dist2{-pi, pi};
210 std::generate(testAngles.begin(), testAngles.end(), [&dist, &dist2, &mt] {
211 return std::tuple<double, double, double>{dist2(mt), dist(mt), dist2(mt)};
212 });
213
214 testAngles.emplace_back(-pi, pi / 2.0, 0);
215 for (auto a : testAngles) {
216 auto [yaw, pitch, roll] = a;
217 auto m = o2::mch::geo::angles2matrix(yaw, pitch, roll);
218 auto [y, p, r] = o2::mch::geo::matrix2angles(m);
219 BOOST_TEST_INFO_SCOPE(fmt::format(
220 " input yaw {:7.2f} pitch {:7.2f} roll {:7.2f}\n"
221 "output yaw {:7.2f} pitch {:7.2f} roll {:7.2f}\n",
222 yaw, pitch, roll,
223 y, p, r));
224 BOOST_CHECK_CLOSE(y, yaw, 1E-6);
225 BOOST_CHECK_CLOSE(p, pitch, 1E-6);
226 BOOST_CHECK_CLOSE(r, roll, 1E-6);
227 }
228}
int32_t i
Interface for MCH geometry creation.
BOOST_DATA_TEST_CASE(DefaultConstructorNofSamplesIsInvariant, boost::unit_test::data::make(nsamples), nofSamples)
Definition testDigit.cxx:50
GLdouble n
Definition glcorearb.h:1982
const GLfloat * m
Definition glcorearb.h:4066
GLdouble GLdouble GLdouble GLdouble top
Definition glcorearb.h:4077
GLdouble GLdouble right
Definition glcorearb.h:4077
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint y
Definition glcorearb.h:270
GLboolean r
Definition glcorearb.h:1233
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
void addAlignableVolumes(TGeoManager &geom)
Definition Geometry.cxx:99
TransformationCreator transformationFromJSON(std::istream &in)
std::tuple< double, double, double > matrix2angles(gsl::span< double > rot)
std::array< int, 156 > allDeIds
std::array< double, 9 > angles2matrix(double yaw, double pitch, double roll)
TransformationCreator transformationFromTGeoManager(const TGeoManager &geo)
std::function< o2::math_utils::Transform3D(int detElemId)> TransformationCreator
void createStandaloneGeometry()
Definition Helpers.cxx:112
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::map< std::string, ID > expected
auto transformation
constexpr CoarseLocation topLeft
constexpr CoarseLocation bottomRight
bool operator==(const CoarseLocation &a, const CoarseLocation &b)
constexpr double rad2deg
BOOST_AUTO_TEST_CASE(Angle2Matrix2Angle)
CoarseLocation getDetElemCoarseLocation(int detElemId, o2::mch::geo::TransformationCreator transformation)
void setExpectation(int firstDeId, int lastDeId, CoarseLocation q, std::map< int, CoarseLocation > &expected)
constexpr CoarseLocation bottomLeft
std::string asString(const CoarseLocation &q)
constexpr CoarseLocation topRight
constexpr int ntrans
constexpr double deg2rad
void dumpMat(gsl::span< double > m)
std::random_device rd
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())