Project
Loading...
Searching...
No Matches
testClusterizer.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
16
17#define BOOST_TEST_MODULE midClustering
18#define BOOST_TEST_DYN_LINK
19#include <boost/test/unit_test.hpp>
20// Keep this separate or clang format will sort the include
21// thus breaking compilation
22#include <boost/test/data/monomorphic.hpp>
23#include <boost/test/data/monomorphic/generators/xrange.hpp>
24#include <boost/test/data/test_case.hpp>
25#include <cstdint>
26#include <iostream>
27#include <vector>
28#include <random>
29#include <gsl/gsl>
34
35namespace o2
36{
37namespace mid
38{
39
40std::vector<ColumnData> getColumnsFixed(int event)
41{
42 std::vector<ColumnData> columns;
43 switch (event) {
44 case 0:
45 columns.emplace_back(ColumnData());
46 columns.back().deId = 31;
47 columns.back().columnId = 1;
48 columns.back().setNonBendPattern(1 << 4 | 1 << 5 | 1 << 7);
49 columns.back().setBendPattern(1 << 14 | 1 << 15, 0);
50 columns.back().setBendPattern(1 << 0 | 1 << 1, 1);
51 columns.emplace_back(ColumnData());
52 columns.back().deId = 31;
53 columns.back().columnId = 2;
54 columns.back().setNonBendPattern(1 << 0);
55 columns.back().setBendPattern(1 << 0, 1);
56 break;
57 case 1:
58 columns.emplace_back(ColumnData());
59 columns.back().deId = 68;
60 columns.back().columnId = 0;
61 columns.back().setNonBendPattern(1 << 2 | 1 << 3 | 1 << 15);
62 columns.back().setBendPattern(1 << 14 | 1 << 15, 2);
63 columns.back().setBendPattern(1 << 0 | 1 << 1, 3);
64 columns.emplace_back(ColumnData());
65 columns.back().deId = 68;
66 columns.back().columnId = 1;
67 columns.back().setNonBendPattern(1 << 0);
68 columns.back().setBendPattern(1 << 1, 3);
69 break;
70 case 2:
71 columns.emplace_back(ColumnData());
72 columns.back().deId = 31;
73 columns.back().columnId = 1;
74 columns.back().setNonBendPattern(1 << 7);
75 columns.back().setBendPattern(1 << 14 | 1 << 15, 0);
76 columns.back().setBendPattern(1 << 0 | 1 << 1, 1);
77 columns.emplace_back(ColumnData());
78 columns.back().deId = 31;
79 columns.back().columnId = 2;
80 columns.back().setNonBendPattern(1 << 0);
81 columns.back().setBendPattern(1 << 14 | 1 << 15, 0);
82 columns.back().setBendPattern(1 << 0 | 1 << 1, 1);
83 break;
84 default:
85 std::cerr << "Event " << event << "not defined" << std::endl;
86 }
87
88 return columns;
89}
90
91std::vector<Cluster> getClusters(int event)
92{
93 std::vector<Cluster> clusters;
94 Cluster clus;
95 switch (event) {
96 case 0:
97 clus.deId = 31; // LegacyUtility::convertFromLegacyDeId(1400);
98 clus.xCoor = -98.0417;
99 clus.yCoor = -18.2403;
100 clus.xErr = 1.3163814;
101 clus.yErr = 1.3163814;
102 clusters.push_back(clus);
103 clus.deId = 31; // LegacyUtility::convertFromLegacyDeId(1400);
104 clus.xCoor = -91.8856;
105 clus.yCoor = -18.1263;
106 clus.xErr = 1.1247177;
107 clus.yErr = 1.2082798;
108 clusters.push_back(clus);
109 break;
110 case 1:
111 clus.deId = 68; // LegacyUtility::convertFromLegacyDeId(1408);
112 clus.xCoor = -129.962;
113 clus.yCoor = 18.2403;
114 clus.xErr = 1.3163814;
115 clus.yErr = 1.3163814;
116 clusters.push_back(clus);
117 clus.deId = 68; // LegacyUtility::convertFromLegacyDeId(1408);
118 clus.xCoor = -101.006;
119 clus.yCoor = 18.5823;
120 clus.xErr = 1.1247177;
121 clus.yErr = 1.3695948;
122 clusters.push_back(clus);
123 break;
124 case 2:
125 clus.deId = 31; // LegacyUtility::convertFromLegacyDeId(1400);
126 clus.xCoor = -91.2016;
127 clus.yCoor = -18.2403;
128 clus.xErr = 1.3163814;
129 clus.yErr = 1.3163814;
130 clusters.push_back(clus);
131 break;
132 default:
133 std::cerr << "Event " << event << "not defined" << std::endl;
134 }
135
136 return clusters;
137}
138
139bool areClustersEqual(const Cluster& cl1, const Cluster& cl2)
140{
141 int nBad = 0;
142 float precision = 1.e-3;
143 if (cl1.deId != cl2.deId) {
144 std::cerr << "Id: " << static_cast<int>(cl1.deId) << " != " << static_cast<int>(cl2.deId) << std::endl;
145 ++nBad;
146 }
147
148 if (std::abs(cl1.xCoor - cl2.xCoor) > precision) {
149 std::cerr << "xCoor: " << cl1.xCoor << " != " << cl2.xCoor << std::endl;
150 ++nBad;
151 }
152
153 if (std::abs(cl1.yCoor - cl2.yCoor) > precision) {
154 std::cerr << "yCoor: " << cl1.yCoor << " != " << cl2.yCoor << std::endl;
155 ++nBad;
156 }
157
158 if (std::abs(cl1.xErr - cl2.xErr) > precision) {
159 std::cerr << "xErr: " << cl1.xErr << " != " << cl2.xErr << std::endl;
160 ++nBad;
161 }
162
163 if (std::abs(cl1.yErr - cl2.yErr) > precision) {
164 std::cerr << "yErr: " << cl1.yErr << " != " << cl2.yErr << std::endl;
165 ++nBad;
166 }
167
168 return (nBad == 0);
169}
170
171class MyFixture
172{
173 public:
181};
182
183BOOST_DATA_TEST_CASE_F(MyFixture, MID_Clustering_Fixed, boost::unit_test::data::xrange(3))
184{
185 preClusterizer.process(getColumnsFixed(sample));
186 gsl::span<const PreCluster> preClusters(preClusterizer.getPreClusters().data(), preClusterizer.getPreClusters().size());
187
188 clusterizer.process(preClusters);
189 std::vector<Cluster> clusters = getClusters(sample);
190 BOOST_TEST(clusters.size() == clusterizer.getClusters().size());
191 size_t minNcl = clusters.size();
192 if (clusterizer.getClusters().size() < minNcl) {
193 minNcl = clusterizer.getClusters().size();
194 }
195 for (size_t icl = 0; icl < minNcl; ++icl) {
196 BOOST_TEST(areClustersEqual(clusters[icl], clusterizer.getClusters()[icl]));
197 }
198}
199
200bool isWithinUncertainties(float xPos, float yPos, const Cluster& cl)
201{
202 std::string str[2] = {"x", "y"};
203 float inputPos[2] = {xPos, yPos};
204 float recoPos[2] = {cl.xCoor, cl.yCoor};
205 float err[2] = {cl.xErr, cl.yErr};
206 bool isOk = true;
207 for (int icoor = 0; icoor < 2; ++icoor) {
208 if (err[icoor] > 5. || std::abs(recoPos[icoor] - inputPos[icoor]) > 5 * err[icoor]) {
209 std::cerr << str[icoor] << " position input " << inputPos[icoor] << " reco " << recoPos[icoor] << " sigma "
210 << err[icoor] << std::endl;
211 isOk = false;
212 }
213 }
214 return isOk;
215}
216
217std::vector<ColumnData> getFiredStrips(float xPos, float yPos, int deId, const Mapping& mapping)
218{
219 // This is a quite simple case just for testing purposes.
220 // The fired strips are simply the fired strip itself + its neighbours.
221 // However, in the bending plane, this also consists of strips with no overlap
222 // with the non-bending plane
223 std::vector<ColumnData> columns;
224 for (int cathode = 1; cathode >= 0; --cathode) {
225 Mapping::MpStripIndex stripIndex = mapping.stripByPosition(xPos, yPos, cathode, deId, false);
226 if (!stripIndex.isValid()) {
227 continue;
228 }
229 std::vector<Mapping::MpStripIndex> neighbours = mapping.getNeighbours(stripIndex, cathode, deId);
230 neighbours.push_back(stripIndex);
231 for (auto& neigh : neighbours) {
232 ColumnData* columnStruct = nullptr;
233 for (auto& currCol : columns) {
234 if (currCol.columnId == neigh.column) {
235 columnStruct = &currCol;
236 break;
237 }
238 }
239 if (!columnStruct) {
240 if (cathode == 0) {
241 // For the sake of simplicity we reject the neighbour bending strips
242 // that do not overlap to the non-bending plane
243 continue;
244 }
245 columns.emplace_back(ColumnData());
246 columnStruct = &columns.back();
247 columnStruct->deId = deId;
248 columnStruct->columnId = neigh.column;
249 }
250 columnStruct->addStrip(neigh.strip, cathode, neigh.line);
251 }
252 }
253 return columns;
254}
255
256BOOST_DATA_TEST_CASE_F(MyFixture, MID_Clustering_Random, boost::unit_test::data::xrange(72), deId)
257{
258 std::random_device rd;
259 std::mt19937 mt(rd());
260 std::uniform_real_distribution<float> distX(-127.5, 127.5);
261 std::uniform_real_distribution<float> distY(-68., 68.);
262
263 for (int ievt = 0; ievt < 1000; ++ievt) {
264 float xPos = distX(mt);
265 float yPos = distY(mt);
266 std::vector<ColumnData> columns = getFiredStrips(xPos, yPos, deId, mapping);
267 if (columns.size() == 0) {
268 // Position was outside detection element
269 continue;
270 }
271 preClusterizer.process(columns);
272 gsl::span<const PreCluster> preClusters(preClusterizer.getPreClusters().data(), preClusterizer.getPreClusters().size());
273 clusterizer.process(preClusters);
274 BOOST_TEST(clusterizer.getClusters().size() == 1);
275
276 for (const auto& clus : clusterizer.getClusters()) {
277 BOOST_TEST(isWithinUncertainties(xPos, yPos, clus));
278 }
279 }
280}
281
282} // namespace mid
283} // namespace o2
Strip pattern (aka digits)
Reconstructed MID cluster.
Cluster reconstruction algorithm for MID.
Pre-cluster reconstruction algorithm for MID.
Clusterizing algorithm for MID.
Definition Clusterizer.h:38
bool init(std::function< void(size_t, size_t)> func=[](size_t, size_t) {})
MpStripIndex stripByPosition(double xPos, double yPos, int cathode, int deId, bool warn=true) const
Definition Mapping.cxx:592
std::vector< MpStripIndex > getNeighbours(const Mapping::MpStripIndex &stripIndex, int cathode, int deId) const
Definition Mapping.cxx:227
PreClusterizer preClusterizer
Pre-clustering algorithm for MID.
struct _cl_event * event
Definition glcorearb.h:2982
GLenum GLint GLint * precision
Definition glcorearb.h:1899
std::vector< ColumnData > getFiredStrips(float xPos, float yPos, int deId, const Mapping &mapping)
std::mt19937 mt(rd())
bool isWithinUncertainties(float xPos, float yPos, const Cluster &cl)
std::uniform_real_distribution< float > distX(-127.5, 127.5)
std::uniform_real_distribution< float > distY(-68., 68.)
BOOST_TEST(clusters.size()==clusterizer.getClusters().size())
bool areClustersEqual(const Cluster &cl1, const Cluster &cl2)
std::vector< Cluster > clusters
std::vector< Cluster > getClusters(int event)
gsl::span< const PreCluster > preClusters(preClusterizer.getPreClusters().data(), preClusterizer.getPreClusters().size())
std::vector< ColumnData > getColumnsFixed(int event)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
cluster structure for MID
Definition Cluster.h:30
float yErr
Cluster resolution along y.
Definition Cluster.h:35
float yCoor
y coordinate
Definition Cluster.h:32
float xErr
Cluster resolution along x.
Definition Cluster.h:34
float xCoor
x coordinate
Definition Cluster.h:31
uint8_t deId
Detection element ID.
Definition Cluster.h:36
Column data structure for MID.
Definition ColumnData.h:29
uint8_t columnId
Column in DE.
Definition ColumnData.h:31
void addStrip(int strip, int cathode, int line)
uint8_t deId
Index of the detection element.
Definition ColumnData.h:30
Indexes required to define a strip in the detection element.
Definition Mapping.h:34
bool isValid()
Check if Strip is Valid.
Definition Mapping.h:36
std::random_device rd
const std::string str