Project
Loading...
Searching...
No Matches
CathodeSegmentationLong.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_DYN_LINK
16
17#include <boost/test/unit_test.hpp>
18
19#include <boost/format.hpp>
24#include <boost/test/data/monomorphic.hpp>
25#include <boost/test/data/monomorphic/generators/xrange.hpp>
26#include <boost/test/data/test_case.hpp>
27#include <fstream>
28#include <iostream>
29#include "TestParameters.h"
30#include "InputDocument.h"
31
32using namespace o2::mch::mapping;
33namespace bdata = boost::unit_test::data;
34
35using Point = std::pair<double, double>;
36
37BOOST_AUTO_TEST_SUITE(o2_mch_mapping)
38BOOST_AUTO_TEST_SUITE(cathode_segmentation_long)
39
40void dumpToFile(std::string fileName, const CathodeSegmentation& seg, const std::vector<Point>& points)
41{
42 std::ofstream out(fileName);
44
46
47 svgCathodeSegmentation(seg, w, true, true, true, false);
48
49 w.svgGroupStart("testpoints");
50 w.points(points, 0.1);
51 w.svgGroupEnd();
52 w.writeHTML(out);
53}
54
57std::vector<Point> checkGaps(const CathodeSegmentation& seg, double xstep = 1.0, double ystep = 1.0)
58{
59 std::vector<Point> gaps;
62
63 if (env.size() != 1) {
64 throw std::runtime_error("assumption env contour = one polygon is not verified");
65 }
66
67 for (double x = bbox.xmin() - xstep; x <= bbox.xmax() + xstep; x += xstep) {
68 for (double y = bbox.ymin() - ystep; y <= bbox.ymax() + ystep; y += ystep) {
69 double distanceToEnveloppe =
71 bool withinEnveloppe = env.contains(x, y) && (distanceToEnveloppe > 1E-5);
72 if (withinEnveloppe && !seg.isValid(seg.findPadByPosition(x, y))) {
73 gaps.emplace_back(x, y);
74 }
75 }
76 }
77 return gaps;
78}
79
80BOOST_TEST_DECORATOR(*boost::unit_test::label("long"))
81BOOST_DATA_TEST_CASE(NoGapWithinPads,
82 boost::unit_test::data::make({100, 300, 500, 501, 502, 503, 504, 600, 601, 602, 700,
83 701, 702, 703, 704, 705, 706, 902, 903, 904, 905}) *
84 boost::unit_test::data::make({true, false}),
85 detElemId, isBendingPlane)
86{
88 auto g = checkGaps(seg);
89
90 if (!g.empty()) {
91 dumpToFile("bug-gap-" + std::to_string(detElemId) + "-" + (isBendingPlane ? "B" : "NB") + ".html", seg, g);
92 }
93 BOOST_TEST(g.empty());
94}
95
96bool areEqual(double a, double b)
97{
98 return std::fabs(b - a) < 1E-4; // 1E-4 cm = 1 micron
99}
100
101using Comparator = std::function<int(const o2::mch::mapping::CathodeSegmentation&, int, rapidjson::Value&)>;
102
103int testOne(const o2::mch::mapping::CathodeSegmentation& seg, rapidjson::Value& tp,
104 Comparator comp)
105{
106 double x = tp["x"].GetDouble();
107 double y = tp["y"].GetDouble();
108 int catPadIndex = seg.findPadByPosition(x, y);
109
110 bool isOutside{false};
111
112 if (tp.HasMember("isoutside")) {
113 isOutside = (tp["isoutside"].GetString() == std::string("true"));
114 }
115
116 if (seg.isValid(catPadIndex) && isOutside) {
117 std::cerr << "found a pad where I was not expecting one" << std::endl;
118 return 1;
119 }
120 if (!seg.isValid(catPadIndex) && !isOutside) {
121 std::cerr << "did not find a pad where I was expecting one" << std::endl;
122 return 1;
123 }
124
125 if (seg.isValid(catPadIndex)) {
126 return comp(seg, catPadIndex, tp);
127 }
128 return 0;
129}
130
131void TestWithComparator(Comparator comp, const char* msg)
132{
134
135 std::string filepath{params.path};
136
137 if (filepath.empty()) {
138 BOOST_TEST(true, "skipping test as no --testpos given");
139 return;
140 }
141 InputWrapper data(filepath.c_str());
142
143 rapidjson::Value& test_positions = data.document()["testpositions"];
144
145 BOOST_TEST(test_positions.Size() > 0);
146
147 int notok{0};
148
149 int ntested{0};
150
151 for (auto& tp : test_positions.GetArray()) {
152 int detElemId = tp["de"].GetInt();
153 bool isBendingPlane = (tp["bending"].GetString() == std::string("true"));
155 notok += testOne(seg, tp, comp);
156 ++ntested;
157 }
158 std::cout << ntested << " tested for " << msg << ": " << notok << " found not ok\n";
159 BOOST_TEST(notok == 0);
160}
161
162// BOOST_TEST_DECORATOR( * boost::unit_test::precondition(TestParameters{}) *boost::unit_test::label("long"))
163// not using precondition as it is (wrongly ?) reported as an error in the run summary ?
164BOOST_TEST_DECORATOR(*boost::unit_test::label("long"))
166{
168 int catPadIndex, rapidjson::Value& tp) -> int {
169 double px = seg.padPositionX(catPadIndex);
170 double py = seg.padPositionY(catPadIndex);
171 double ex = tp["px"].GetDouble();
172 double ey = tp["py"].GetDouble();
173 if (!areEqual(px, ex) || !areEqual(py, ey)) {
174 std::cout << "got different positions here : got px,py=" << px << "," << py << " vs expected x,y=" << ex << ","
175 << ey << std::endl;
176 return 1;
177 }
178 return 0;
179 },
180 "(x,y) positions");
181}
182
183BOOST_TEST_DECORATOR(*boost::unit_test::label("long"))
184BOOST_AUTO_TEST_CASE(TestChannelNumbers)
185{
187
189 int catPadIndex, rapidjson::Value& tp)
190 -> int {
191 auto dsid = seg.padDualSampaId(catPadIndex);
192 auto dsch = seg.padDualSampaChannel(catPadIndex);
193
194 if (params.isTestFileInManuNumbering && params.isSegmentationRun3) {
195 dsch = ds2manu(tp["de"].GetInt(), dsch);
196 }
197
198 if (!params.isTestFileInManuNumbering && !params.isSegmentationRun3) {
199 dsch = manu2ds(tp["de"].GetInt(), dsch);
200 }
201
202 int eid = tp["dsid"].GetInt();
203 int ech = tp["dsch"].GetInt();
204 if (!areEqual(dsid, eid) || !areEqual(dsch, ech)) {
205 std::cout << "got different channel numbering for de " << tp["de"].GetInt() << " (dsid,dsch) " << dsid << "," << dsch << " vs expected =" << eid << "," << ech << std::endl;
206 return 1;
207 }
208 return 0;
209 },
210 "channel numbering");
211}
212
213BOOST_TEST_DECORATOR(*boost::unit_test::label("long"))
214BOOST_AUTO_TEST_CASE(TestCathodeForEachPadAndPadIndexRange)
215{
217 for (auto plane : { true, false }) {
218 int n = 0;
219 int pmin = std::numeric_limits<int>::max();
220 int pmax = 0;
221 CathodeSegmentation catseg{ detElemId, plane };
222 catseg.forEachPad([&n,&pmin,&pmax](int dePadIndex) {
223 n++;
224 pmin = std::min(pmin,dePadIndex);
225 pmax = std::max(pmax,dePadIndex);
226 });
227 BOOST_CHECK_EQUAL(n, catseg.nofPads());
228 BOOST_CHECK_EQUAL(pmin,0);
229 BOOST_CHECK_EQUAL(pmax,catseg.nofPads()-1);
230 } });
231}
232
233BOOST_AUTO_TEST_SUITE_END()
234BOOST_AUTO_TEST_SUITE_END()
bool isBendingPlane
o2::mch::mapping::CathodeSegmentation seg
void dumpToFile(std::string fileName, const CathodeSegmentation &seg, const std::vector< Point > &points)
std::vector< Point > checkGaps(const CathodeSegmentation &seg, double xstep=1.0, double ystep=1.0)
int testOne(const o2::mch::mapping::CathodeSegmentation &seg, rapidjson::Value &tp, Comparator comp)
void TestWithComparator(Comparator comp, const char *msg)
bool areEqual(double a, double b)
std::pair< double, double > Point
BOOST_AUTO_TEST_CASE(TestPositions)
BOOST_DATA_TEST_CASE(NoGapWithinPads, boost::unit_test::data::make({100, 300, 500, 501, 502, 503, 504, 600, 601, 602, 700, 701, 702, 703, 704, 705, 706, 902, 903, 904, 905}) *boost::unit_test::data::make({true, false}), detElemId, isBendingPlane)
std::function< int(const o2::mch::mapping::CathodeSegmentation &, int, rapidjson::Value &)> Comparator
A CathodeSegmentation lets you find pads on a given plane (cathode) of a detection element and then i...
int padDualSampaChannel(int catPadIndex) const
int padDualSampaId(int catPadIndex) const
int findPadByPosition(double x, double y) const
double padPositionY(int catPadIndex) const
double padPositionX(int catPadIndex) const
bool isValid(int catPadIndex) const
Not every integer is a valid catPadIndex. This method will tell if catPadIndex is a valid one.
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLenum const GLfloat * params
Definition glcorearb.h:272
GLboolean * data
Definition glcorearb.h:298
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLboolean GLboolean g
Definition glcorearb.h:1233
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
auto squaredDistancePointToPolygon(const Vertex< T > &point, const Polygon< T > &polygon) -> decltype(point.x *point.x)
Definition Polygon.h:278
int detElemId(Chamber chamber, Side side, int number)
std::string svgCathodeSegmentationDefaultStyle()
void svgCathodeSegmentation(const CathodeSegmentation &seg, o2::mch::contour::SVGWriter &writer, bool showdes, bool showdualsampas, bool showpads, bool showpadchannels)
void forOneDetectionElementOfEachSegmentationType(CALLABLE &&func)
o2::mch::contour::BBox< double > getBBox(const CathodeSegmentation &seg)
o2::mch::contour::Contour< double > getEnvelop(const CathodeSegmentation &seg)
Defining DataPointCompositeObject explicitly as copiable.
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
std::string path
BOOST_TEST(digits==digitsD, boost::test_tools::per_element())
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())
uint64_t const void const *restrict const msg
Definition x9.h:153