ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ClusterizationTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ClusterizationTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018 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/data/test_case.hpp>
10 #include <boost/test/unit_test.hpp>
11 
12 #include <algorithm>
13 #include <chrono>
14 #include <ctime>
15 #include <unordered_map>
16 #include <utility>
17 #include <vector>
18 
22 
23 namespace bdata = boost::unit_test::data;
24 namespace tt = boost::test_tools;
25 
26 namespace Acts {
27 
28 namespace Test {
29 
44 BOOST_AUTO_TEST_CASE(create_Clusters1) {
45  size_t nBins0 = 10;
46  std::vector<size_t> clusterSizes = {2, 2, 2, 3, 6, 6, 7};
47  std::vector<size_t> clusterSizesCut = {1, 1, 1, 1, 1, 1, 1, 2, 2, 3};
48  std::vector<size_t> clusterSizesEdge = {1, 1, 1, 1, 1, 1, 1,
49  2, 2, 2, 3, 3, 3, 6};
50  size_t nClusters = clusterSizes.size();
51  size_t nClustersCut = clusterSizesCut.size();
52  size_t nClustersEdge = clusterSizesEdge.size();
53 
54  auto globalIndex = [&nBins0](const size_t& a, const size_t& b) {
55  return (a + nBins0 * b);
56  };
57 
58  std::unordered_map<size_t, std::pair<Acts::DigitizationCell, bool>> testCells;
59  // add cells covering all cases
60  testCells.insert(
61  {globalIndex(0, 0), {Acts::DigitizationCell(0, 0, 1), false}});
62  testCells.insert(
63  {globalIndex(0, 3), {Acts::DigitizationCell(0, 3, 1), false}});
64  testCells.insert(
65  {globalIndex(0, 4), {Acts::DigitizationCell(0, 4, 1), false}});
66  testCells.insert(
67  {globalIndex(0, 8), {Acts::DigitizationCell(0, 8, 1), false}});
68  testCells.insert(
69  {globalIndex(1, 1), {Acts::DigitizationCell(1, 1, 1), false}});
70  testCells.insert(
71  {globalIndex(1, 8), {Acts::DigitizationCell(1, 8, 1), false}});
72  testCells.insert(
73  {globalIndex(2, 5), {Acts::DigitizationCell(2, 5, 1), false}});
74  testCells.insert(
75  {globalIndex(2, 8), {Acts::DigitizationCell(2, 8, 1), false}});
76  testCells.insert(
77  {globalIndex(3, 1), {Acts::DigitizationCell(3, 1, 1), false}});
78  testCells.insert(
79  {globalIndex(3, 4), {Acts::DigitizationCell(3, 4, 1), false}});
80  testCells.insert(
81  {globalIndex(3, 6), {Acts::DigitizationCell(3, 6, 1), false}});
82  testCells.insert(
83  {globalIndex(4, 0), {Acts::DigitizationCell(4, 0, 1), false}});
84  testCells.insert(
85  {globalIndex(4, 6), {Acts::DigitizationCell(4, 6, 1), false}});
86  testCells.insert(
87  {globalIndex(5, 3), {Acts::DigitizationCell(5, 3, 1), false}});
88  testCells.insert(
89  {globalIndex(5, 5), {Acts::DigitizationCell(5, 5, 1), false}});
90  testCells.insert(
91  {globalIndex(5, 4), {Acts::DigitizationCell(5, 4, 1), false}});
92  testCells.insert(
93  {globalIndex(5, 5), {Acts::DigitizationCell(5, 5, 1), false}});
94  testCells.insert(
95  {globalIndex(7, 1), {Acts::DigitizationCell(7, 1, 1), false}});
96  testCells.insert(
97  {globalIndex(7, 2), {Acts::DigitizationCell(7, 2, 1), false}});
98  testCells.insert(
99  {globalIndex(7, 5), {Acts::DigitizationCell(7, 5, 1), false}});
100  testCells.insert(
101  {globalIndex(7, 6), {Acts::DigitizationCell(7, 6, 1), false}});
102  testCells.insert(
103  {globalIndex(8, 2), {Acts::DigitizationCell(8, 2, 1), false}});
104  testCells.insert(
105  {globalIndex(8, 7), {Acts::DigitizationCell(8, 7, 1), false}});
106  testCells.insert(
107  {globalIndex(9, 0), {Acts::DigitizationCell(9, 0, 1), false}});
108  testCells.insert(
109  {globalIndex(9, 1), {Acts::DigitizationCell(9, 1, 1), false}});
110  testCells.insert(
111  {globalIndex(9, 2), {Acts::DigitizationCell(9, 2, 1), false}});
112  testCells.insert(
113  {globalIndex(9, 4), {Acts::DigitizationCell(9, 4, 1), false}});
114  testCells.insert(
115  {globalIndex(9, 5), {Acts::DigitizationCell(9, 5, 1), false}});
116  testCells.insert(
117  {globalIndex(9, 6), {Acts::DigitizationCell(9, 6, 1), false}});
118 
119  size_t nCellsWithoutDuplicates = testCells.size();
120 
121  std::unordered_map<size_t, std::pair<Acts::DigitizationCell, bool>>
122  testCells1;
123  // add cells covering all cases
124  testCells1.insert(
125  {globalIndex(0, 0), {Acts::DigitizationCell(0, 0, 1), false}});
126  testCells1.insert(
127  {globalIndex(0, 3), {Acts::DigitizationCell(0, 3, 2), false}});
128  testCells1.insert(
129  {globalIndex(0, 4), {Acts::DigitizationCell(0, 4, 1), false}});
130  testCells1.insert(
131  {globalIndex(0, 8), {Acts::DigitizationCell(0, 8, 1), false}});
132  testCells1.insert(
133  {globalIndex(1, 1), {Acts::DigitizationCell(1, 1, 2), false}});
134  testCells1.insert(
135  {globalIndex(1, 8), {Acts::DigitizationCell(1, 8, 2), false}});
136  testCells1.insert(
137  {globalIndex(2, 5), {Acts::DigitizationCell(2, 5, 2), false}});
138  testCells1.insert(
139  {globalIndex(2, 8), {Acts::DigitizationCell(2, 8, 2), false}});
140  testCells1.insert(
141  {globalIndex(3, 1), {Acts::DigitizationCell(3, 1, 1), false}});
142  testCells1.insert(
143  {globalIndex(3, 4), {Acts::DigitizationCell(3, 4, 1), false}});
144  testCells1.insert(
145  {globalIndex(3, 6), {Acts::DigitizationCell(3, 6, 1), false}});
146  testCells1.insert(
147  {globalIndex(4, 0), {Acts::DigitizationCell(4, 0, 2), false}});
148  testCells1.insert(
149  {globalIndex(4, 6), {Acts::DigitizationCell(4, 6, 1), false}});
150  testCells1.insert(
151  {globalIndex(5, 3), {Acts::DigitizationCell(5, 3, 1), false}});
152  testCells1.insert(
153  {globalIndex(5, 5), {Acts::DigitizationCell(5, 5, 1), false}});
154  testCells1.insert(
155  {globalIndex(5, 4), {Acts::DigitizationCell(5, 4, 2), false}});
156  testCells1.insert(
157  {globalIndex(5, 5), {Acts::DigitizationCell(5, 5, 1), false}});
158  testCells1.insert(
159  {globalIndex(7, 1), {Acts::DigitizationCell(7, 1, 2), false}});
160  testCells1.insert(
161  {globalIndex(7, 2), {Acts::DigitizationCell(7, 2, 1), false}});
162  testCells1.insert(
163  {globalIndex(7, 5), {Acts::DigitizationCell(7, 5, 1), false}});
164  testCells1.insert(
165  {globalIndex(7, 6), {Acts::DigitizationCell(7, 6, 2), false}});
166  testCells1.insert(
167  {globalIndex(8, 2), {Acts::DigitizationCell(8, 2, 1), false}});
168  testCells1.insert(
169  {globalIndex(8, 7), {Acts::DigitizationCell(8, 7, 2), false}});
170  testCells1.insert(
171  {globalIndex(9, 0), {Acts::DigitizationCell(9, 0, 2), false}});
172  testCells1.insert(
173  {globalIndex(9, 1), {Acts::DigitizationCell(9, 1, 2), false}});
174  testCells1.insert(
175  {globalIndex(9, 2), {Acts::DigitizationCell(9, 2, 2), false}});
176  testCells1.insert(
177  {globalIndex(9, 4), {Acts::DigitizationCell(9, 4, 2), false}});
178  testCells1.insert(
179  {globalIndex(9, 5), {Acts::DigitizationCell(9, 5, 1), false}});
180  testCells1.insert(
181  {globalIndex(9, 6), {Acts::DigitizationCell(9, 6, 1), false}});
182 
183  // add duplicates
184 
185  size_t nCells = testCells1.size();
186 
187  // make copies for all the tests (the boolean in the map gets changed)
188  auto testCells2 = testCells;
189  auto testCells3 = testCells;
190  auto testCells4 = testCells1;
191 
192  // Common Corner, digital,no energy cut
193  // createClusters
194  auto mergedCells1 =
195  Acts::createClusters<Acts::DigitizationCell>(testCells, nBins0, true, 0.);
196  // check number of clusters
197  BOOST_CHECK_EQUAL(mergedCells1.size(), nClusters);
198 
199  float data1 = 0;
200  std::vector<size_t> clusterSizes1;
201  for (size_t i = 0; i < mergedCells1.size(); i++) {
202  auto cells = mergedCells1.at(i);
203  for (auto& cell : cells) {
204  data1 += cell.data;
205  }
206  // check the cluster sizes
207  clusterSizes1.push_back(cells.size());
208  }
209  // check the cluster sizes
210  std::sort(clusterSizes1.begin(), clusterSizes1.end());
211  BOOST_CHECK_EQUAL_COLLECTIONS(clusterSizes.begin(), clusterSizes.end(),
212  clusterSizes1.begin(), clusterSizes1.end());
213  // check cells
214  CHECK_CLOSE_REL(data1, nCellsWithoutDuplicates, 1e-5);
215 
216  // Common Edge, digital,no energy cut
217  // createClusters
218  auto mergedCells2 = Acts::createClusters<Acts::DigitizationCell>(
219  testCells2, nBins0, false, 0.);
220  // check number of clusters
221  BOOST_CHECK_EQUAL(mergedCells2.size(), nClustersEdge);
222 
223  float data2 = 0;
224  std::vector<size_t> clusterSizes2;
225  for (size_t i = 0; i < mergedCells2.size(); i++) {
226  auto cells = mergedCells2.at(i);
227  for (auto& cell : cells) {
228  data2 += cell.data;
229  }
230  // check the cluster sizes
231  clusterSizes2.push_back(cells.size());
232  }
233  // check the cluster sizes
234  std::sort(clusterSizes2.begin(), clusterSizes2.end());
235  BOOST_CHECK_EQUAL_COLLECTIONS(clusterSizesEdge.begin(),
236  clusterSizesEdge.end(), clusterSizes2.begin(),
237  clusterSizes2.end());
238  // check cells
239  CHECK_CLOSE_REL(data2, nCellsWithoutDuplicates, 1e-5);
240 
241  // Common Corner, analogue,no energy cut
242  // createClusters
243  auto mergedCells3 = Acts::createClusters<Acts::DigitizationCell>(
244  testCells3, nBins0, true, 0.);
245  // check number of clusters
246  BOOST_CHECK_EQUAL(mergedCells3.size(), nClusters);
247 
248  float data3 = 0;
249  std::vector<size_t> clusterSizes3;
250  for (size_t i = 0; i < mergedCells3.size(); i++) {
251  auto cells = mergedCells3.at(i);
252  for (auto& cell : cells) {
253  data3 += cell.data;
254  }
255  // check the cluster sizes
256  clusterSizes3.push_back(cells.size());
257  }
258  // check the cluster sizes
259  std::sort(clusterSizes3.begin(), clusterSizes3.end());
260  BOOST_CHECK_EQUAL_COLLECTIONS(clusterSizes.begin(), clusterSizes.end(),
261  clusterSizes3.begin(), clusterSizes3.end());
262  // check cells
263  CHECK_CLOSE_REL(data3, nCells, 1e-5);
264 
265  // Common Corner, analogue, energy cut
266  // createClusters
267  auto mergedCells4 = Acts::createClusters<Acts::DigitizationCell>(
268  testCells4, nBins0, true, 1.5);
269  // check number of clusters
270 
271  BOOST_CHECK_EQUAL(mergedCells4.size(), nClustersCut);
272 
273  float data4 = 0;
274  std::vector<size_t> clusterSizes4;
275  for (size_t i = 0; i < mergedCells4.size(); i++) {
276  auto cells = mergedCells4.at(i);
277  for (auto& cell : cells) {
278  data4 += cell.data;
279  }
280  // check the cluster sizes
281  clusterSizes4.push_back(cells.size());
282  }
283  // check the cluster sizes
284  std::sort(clusterSizes4.begin(), clusterSizes4.end());
285  BOOST_CHECK_EQUAL_COLLECTIONS(clusterSizesCut.begin(), clusterSizesCut.end(),
286  clusterSizes4.begin(), clusterSizes4.end());
287  // check cells
288  CHECK_CLOSE_REL(data4, nCells, 1e-5);
289 }
290 
294 BOOST_AUTO_TEST_CASE(create_Clusters2) {
295  std::unordered_map<size_t, std::pair<Acts::DigitizationCell, bool>>
296  testCells1;
297 
298  size_t nCells = 99;
299  size_t delta = 3;
300  size_t nClustersNoTouch = (nCells / delta) * (nCells / delta);
301  size_t nCellsInClusters = nClustersNoTouch * 3;
302 
303  auto globalIndex = [&nCells](const size_t& a, const size_t& b) {
304  return (a + nCells * b);
305  };
306 
307  // Create clusters which are separated by one cell always
308  // Clusters have the following shape:
309  // -----
310  // --##-
311  // ---#-
312  // -----
313  for (size_t i = 0; i < nCells; i += delta) {
314  for (size_t j = 0; j < nCells; j += delta) {
315  auto cellA = Acts::DigitizationCell(i, j, 1);
316  auto cellB = Acts::DigitizationCell(i, j + 1, 1);
317  auto cellC = Acts::DigitizationCell(i + 1, j + 1, 1);
318 
319  auto insertCellA = testCells1.insert({globalIndex(i, j), {cellA, false}});
320  if (!insertCellA.second) {
321  // check if there is already a cell at same position and merge in that
322  // case
323  insertCellA.first->second.first.addCell(cellA, false);
324  }
325  auto insertCellB =
326  testCells1.insert({globalIndex(i, j + 1), {cellB, false}});
327  if (!insertCellB.second) {
328  // check if there is already a cell at same position and merge in that
329  // case
330  insertCellB.first->second.first.addCell(cellB, false);
331  }
332  auto insertCellC =
333  testCells1.insert({globalIndex(i + 1, j + 1), {cellC, false}});
334  if (!insertCellC.second) {
335  // check if there is already a cell at same position and merge in that
336  // case
337  insertCellC.first->second.first.addCell(cellC, false);
338  }
339  }
340  }
341  // copy
342  auto testCells2 = testCells1;
343  auto testCells3 = testCells1;
344  auto testCells5 = testCells1;
345  auto testCells7 = testCells1;
346  auto testCells8 = testCells1;
347 
348  // in a 99x99 grid we get 33x33=1089 clusters
349  // Now we should have the same number of cluster for common corner and
350  // common edge case
351  // common edge
352  auto mergedCells1 = Acts::createClusters<Acts::DigitizationCell>(
353  testCells1, nCells, true, 0.);
354  BOOST_CHECK_EQUAL(mergedCells1.size(), nClustersNoTouch);
355  // common corner
356  auto mergedCells2 = Acts::createClusters<Acts::DigitizationCell>(
357  testCells2, nCells, false, 0.);
358  BOOST_CHECK_EQUAL(mergedCells2.size(), nClustersNoTouch);
359 
360  // now test merging - there is no merging at the moment
361  float data1 = 0;
362  for (auto& cells : mergedCells1) {
363  for (auto& i : cells) {
364  data1 += i.data;
365  // check cluster sizes
366  BOOST_CHECK_EQUAL(cells.size(), delta);
367  }
368  }
369  CHECK_CLOSE_REL(data1, nCellsInClusters, 1e-5);
370 
371  // now test merging - there is no merging at the moment
372  float data2 = 0;
373  for (auto& cells : mergedCells2) {
374  for (auto& i : cells) {
375  data2 += i.data;
376  // check cluster sizes
377  BOOST_CHECK_EQUAL(cells.size(), delta);
378  }
379  }
380  CHECK_CLOSE_REL(data2, nCellsInClusters, 1e-5);
381 
382  // now we add some cells which lead to merging only for common corner and
383  // create new clusters for edge case)
384  size_t delta2 = 9;
385  size_t nCornerCells = nCells / delta2 * nCells / delta2;
386  size_t nClusters_merged = nClustersNoTouch - nCornerCells * 2;
387 
388  for (size_t i = 2; i < nCells; i += delta2) {
389  for (size_t j = 2; j < nCells; j += delta2) {
390  auto cell = Acts::DigitizationCell(i, j, 1);
391  auto insertCell = testCells3.insert({globalIndex(i, j), {cell, false}});
392  if (!insertCell.second) {
393  // check if there is already a cell at same position and merge in that
394  // case
395  insertCell.first->second.first.addCell(cell, false);
396  }
397  }
398  }
399  auto testCells4 = testCells3;
400 
401  // common corner
402  auto mergedCells3 = Acts::createClusters<Acts::DigitizationCell>(
403  testCells3, nCells, true, 0.);
404  BOOST_CHECK_EQUAL(mergedCells3.size(), nClusters_merged);
405 
406  // common edge
407  auto mergedCells4 = Acts::createClusters<Acts::DigitizationCell>(
408  testCells4, nCells, false, 0.);
409  BOOST_CHECK_EQUAL(mergedCells4.size(), nClustersNoTouch + nCornerCells);
410 
411  // now we add some cells which lead to merging also for edge case
412  for (size_t i = 2; i < nCells; i += delta2) {
413  for (size_t j = 2; j < nCells; j += delta2) {
414  auto cellA = Acts::DigitizationCell(i, j - 1, 1);
415  auto insertCellA =
416  testCells5.insert({globalIndex(i, j - 1), {cellA, false}});
417  if (!insertCellA.second) {
418  // check if there is already a cell at same position and merge in that
419  // case
420  insertCellA.first->second.first.addCell(cellA, false);
421  }
422  auto cellB = Acts::DigitizationCell(i + 1, j, 1);
423  auto insertCellB =
424  testCells5.insert({globalIndex(i + 1, j), {cellB, false}});
425  if (!insertCellB.second) {
426  // check if there is already a cell at same position and merge in that
427  // case
428  insertCellB.first->second.first.addCell(cellB, false);
429  }
430  }
431  }
432  auto testCells6 = testCells5;
433 
434  // common corner
435  auto mergedCells5 = Acts::createClusters<Acts::DigitizationCell>(
436  testCells5, nCells, true, 0.);
437  BOOST_CHECK_EQUAL(mergedCells5.size(), nClusters_merged);
438 
439  // common edge
440  auto mergedCells6 = Acts::createClusters<Acts::DigitizationCell>(
441  testCells6, nCells, false, 0.);
442  BOOST_CHECK_EQUAL(mergedCells6.size(), nClusters_merged);
443 
444  // now adding the same cells again on two positions of clusters - digital
445  // readout
446  for (size_t i = 0; i < nCells; i += delta) {
447  for (size_t j = 0; j < nCells; j += delta) {
448  auto cellA = Acts::DigitizationCell(i, j, 1);
449  auto cellB = Acts::DigitizationCell(i, j + 1, 1);
450 
451  auto insertCellA = testCells7.insert({globalIndex(i, j), {cellA, false}});
452  if (!insertCellA.second) {
453  // check if there is already a cell at same position and merge in that
454  // case
455  insertCellA.first->second.first.addCell(cellA, false);
456  }
457  auto insertCellB =
458  testCells7.insert({globalIndex(i, j + 1), {cellB, false}});
459  if (!insertCellB.second) {
460  // check if there is already a cell at same position and merge in that
461  // case
462  insertCellB.first->second.first.addCell(cellB, false);
463  }
464  // analogue readout
465  insertCellA = testCells8.insert({globalIndex(i, j), {cellA, false}});
466  if (!insertCellA.second) {
467  // check if there is already a cell at same position and merge in that
468  // case
469  insertCellA.first->second.first.addCell(cellA, true);
470  }
471  insertCellB = testCells8.insert({globalIndex(i, j + 1), {cellB, false}});
472  if (!insertCellB.second) {
473  // check if there is already a cell at same position and merge in that
474  // case
475  insertCellB.first->second.first.addCell(cellB, true);
476  }
477  }
478  }
479  auto testCells9 = testCells8;
480 
481  size_t nCellsInClustersDuplicated =
482  nClustersNoTouch * 3 + nClustersNoTouch * 2;
483 
484  // digital readout
485  auto mergedCells7 = Acts::createClusters<Acts::DigitizationCell>(
486  testCells7, nCells, true, 0.);
487  BOOST_CHECK_EQUAL(mergedCells7.size(), nClustersNoTouch);
488  float data7 = 0;
489  for (auto& cells : mergedCells7) {
490  for (auto& i : cells) {
491  data7 += i.data;
492  }
493  BOOST_CHECK_EQUAL(cells.size(), 3u);
494  }
495  CHECK_CLOSE_REL(data7, nCellsInClusters, 1e-5);
496 
497  // analougue readout
498  auto mergedCells8 = Acts::createClusters<Acts::DigitizationCell>(
499  testCells8, nCells, true, 0.);
500  BOOST_CHECK_EQUAL(mergedCells8.size(), nClustersNoTouch);
501  float data8 = 0;
502  for (auto& cells : mergedCells8) {
503  for (auto& i : cells) {
504  data8 += i.data;
505  }
506  BOOST_CHECK_EQUAL(cells.size(), 3u);
507  }
508  CHECK_CLOSE_REL(data8, nCellsInClustersDuplicated, 1e-5);
509 
510  // analougue readout & energy cut
511  auto mergedCells9 = Acts::createClusters<Acts::DigitizationCell>(
512  testCells9, nCells, true, 1.5);
513  BOOST_CHECK_EQUAL(mergedCells9.size(), nClustersNoTouch);
514  float data9 = 0;
515  for (auto& cells : mergedCells9) {
516  for (auto& i : cells) {
517  data9 += i.data;
518  }
519  BOOST_CHECK_EQUAL(cells.size(), 2u);
520  }
521  CHECK_CLOSE_REL(data9, (nClustersNoTouch * 2) * 2, 1e-5);
522 }
523 } // namespace Test
524 } // namespace Acts