12#define BOOST_TEST_MODULE ITSMFT MultiSourceLoading
13#define BOOST_TEST_MAIN
14#define BOOST_TEST_DYN_LINK
15#include <boost/test/unit_test.hpp>
45enum class Corruption {
51class FakeClusterDecoder
54 FakeClusterDecoder(
o2::detectors::DetID::ID detector, std::vector<int> sensorToLayer,
bool disk, Corruption corruption = Corruption::None)
55 : mDetector(detector), mSensorToLayer(std::move(sensorToLayer)), mDisk(disk), mCorruption(corruption)
61 gsl::span<const unsigned char>::iterator& patterns,
65 if (mCorruption == Corruption::NegativeLayer) {
70 if (mCorruption == Corruption::LayerOutOfRange) {
79 const int layer = (sensorID >= 0 &&
static_cast<size_t>(sensorID) < mSensorToLayer.size()) ? mSensorToLayer[sensorID] : -1;
81 decoded.global = {
static_cast<float>(sensorID),
static_cast<float>(cluster.
getRow()),
static_cast<float>(cluster.
getCol())};
82 decoded.cylinderFrame = {10.f + sensorID, 1.f, 2.f, 0.1f};
83 decoded.rowColumnCovariance = {clusterData.sig2Row, 0.f, clusterData.sig2Col};
84 decoded.nPixels = clusterData.nPixels;
85 decoded.layer =
layer;
91 std::vector<int> mSensorToLayer;
93 Corruption mCorruption;
101class PatternContractDecoder
106 gsl::span<const unsigned char>::iterator& patterns,
111 if (dictionary ==
nullptr) {
112 throw std::runtime_error(
"Cluster dictionary is not available");
114 uint32_t nPixels = 1;
117 nPixels =
static_cast<uint32_t
>(
pattern.getNPixels());
121 decoded.global = {1.f, 2.f, 3.f};
122 decoded.cylinderFrame = {4.f, 5.f, 6.f, 0.f};
123 decoded.rowColumnCovariance = {0.1f, 0.f, 0.2f};
124 decoded.nPixels = nPixels;
132 std::vector<SurfaceDescriptor> surfaces;
134 bool valid()
const noexcept {
return layout.
valid(); }
144BuiltLayout makeCombinedLayout()
146 std::vector<SurfaceDescriptor> surfaces;
147 surfaces.push_back(
SurfaceDescriptor{0,
static_cast<uint8_t
>(o2::detectors::DetID::ITS), SurfaceKind::Cylinder});
148 surfaces.push_back(
SurfaceDescriptor{1,
static_cast<uint8_t
>(o2::detectors::DetID::ITS), SurfaceKind::Cylinder});
149 surfaces.push_back(
SurfaceDescriptor{0,
static_cast<uint8_t
>(o2::detectors::DetID::MFT), SurfaceKind::Disk});
150 surfaces.push_back(
SurfaceDescriptor{1,
static_cast<uint8_t
>(o2::detectors::DetID::MFT), SurfaceKind::Disk});
151 const std::vector<uint16_t> componentOffsets = {0, 2};
155void configureFrame(
TimeFrame& frame,
const BuiltLayout& built)
158 0, 0, std::make_shared<BoundedMemoryResource>()));
163constexpr std::array<unsigned char, 3> onePixelPattern{1, 1, 0x80};
165std::vector<unsigned char> makePatternBytes(
size_t nClusters)
167 std::vector<unsigned char> bytes;
168 bytes.reserve(
nClusters * onePixelPattern.size());
170 bytes.insert(bytes.end(), onePixelPattern.begin(), onePixelPattern.end());
181const std::array<LayerId, 2> itsLayerToSurface{
LayerId{0},
LayerId{1}};
182const std::array<LayerId, 2> mftLayerToSurface{
LayerId{2},
LayerId{3}};
183const std::array<LayerId, 1> firstITSSurface{
LayerId{0}};
184const std::array<LayerId, 1> secondITSSurface{
LayerId{1}};
185const std::array<LayerId, 1> firstMFTSurface{
LayerId{2}};
191 const auto layout = makeCombinedLayout();
192 BOOST_REQUIRE(layout.valid());
194 const std::vector<CompClusterExt>
clusters{
198 const auto patterns = makePatternBytes(
clusters.size());
199 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 2}};
201 FakeClusterDecoder decoder{o2::detectors::DetID::ITS, {0, 1},
false};
204 src.detector = o2::detectors::DetID::ITS;
206 src.patterns = patterns;
208 src.dictionary = &dict();
209 src.layerToSurface = itsLayerToSurface;
211 src.setDecoder(decoder);
214 configureFrame(frame, layout);
215 std::vector<std::vector<uint32_t>> externalIndicesBySurface;
216 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0},
217 &externalIndicesBySurface));
227 auto layout = makeCombinedLayout();
228 layout.layout.systError2Row = {0.01f, 0.f, 0.03f, 0.f};
229 layout.layout.systError2Col = {0.f, 0.02f, 0.f, 0.04f};
231 configureFrame(frame, layout);
235 const auto patterns = makePatternBytes(
clusters.size());
236 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 2}};
237 FakeClusterDecoder itsDecoder{o2::detectors::DetID::ITS, {0, 1},
false};
238 FakeClusterDecoder mftDecoder{o2::detectors::DetID::MFT, {0, 1},
true};
242 std::array<test::TestClusterSourceInput, 2>
sources;
243 for (uint16_t
i = 0;
i <
sources.size(); ++
i) {
246 source.detector =
i == 0 ? o2::detectors::DetID::ITS : o2::detectors::DetID::MFT;
248 source.patterns = patterns;
250 source.dictionary = &dict();
251 source.layerToSurface =
i == 0 ? itsMapping : mftMapping;
253 source.setDecoder(
i == 0 ? itsDecoder : mftDecoder);
256 for (
int reload = 0; reload < 2; ++reload) {
257 BOOST_REQUIRE_NO_THROW(test::loadTimeFrameSources(frame,
sources, layout.getCatalog(), {0, 0}));
258 for (uint16_t surface = 0; surface < 4; ++surface) {
262 BOOST_REQUIRE(measurement);
267 BOOST_REQUIRE_EQUAL(globals.size(), 1u);
268 const auto& covariance = globals.front().covariance;
270 const float sine = std::sin(0.1f), cosine = std::cos(0.1f);
287 const auto layout = makeCombinedLayout();
288 BOOST_REQUIRE(layout.valid());
291 const auto patterns = makePatternBytes(
clusters.size());
292 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 1}};
294 FakeClusterDecoder decoder{o2::detectors::DetID::ITS, {0},
false};
297 src.detector = o2::detectors::DetID::ITS;
299 src.patterns = patterns;
301 src.dictionary = &dict();
302 src.layerToSurface = itsLayerToSurface;
303 src.setDecoder(decoder);
306 configureFrame(frame, layout);
307 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0}));
314 const auto layout = makeCombinedLayout();
315 BOOST_REQUIRE(layout.valid());
317 const std::vector<CompClusterExt>
clusters{
321 const auto patterns = makePatternBytes(
clusters.size());
322 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 2}};
324 FakeClusterDecoder decoder{o2::detectors::DetID::MFT, {0, 1},
true};
327 src.detector = o2::detectors::DetID::MFT;
329 src.patterns = patterns;
331 src.dictionary = &dict();
332 src.layerToSurface = mftLayerToSurface;
334 src.setDecoder(decoder);
337 configureFrame(frame, layout);
338 std::vector<std::vector<uint32_t>> externalIndicesBySurface;
339 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0},
340 &externalIndicesBySurface));
349 const auto layout = makeCombinedLayout();
350 BOOST_REQUIRE(layout.valid());
355 const auto itsPatterns = makePatternBytes(itsClusters.size());
356 const std::vector<ROFRecord> itsRofs{
ROFRecord{{0, 0}, 0, 0, 2},
359 FakeClusterDecoder itsDecoder{o2::detectors::DetID::ITS, {0, 1},
false};
362 const auto mftPatterns = makePatternBytes(mftClusters.size());
363 const std::vector<ROFRecord> mftRofs{
ROFRecord{{0, 0}, 0, 0, 1}};
364 FakeClusterDecoder mftDecoder{o2::detectors::DetID::MFT, {1},
true};
368 std::array<test::TestClusterSourceInput, 2>
sources{};
370 sources[0].detector = o2::detectors::DetID::ITS;
371 sources[0].clusters = itsClusters;
372 sources[0].patterns = itsPatterns;
374 sources[0].dictionary = &dict();
375 sources[0].layerToSurface = itsMapping;
377 sources[0].setDecoder(itsDecoder);
380 sources[1].detector = o2::detectors::DetID::MFT;
381 sources[1].clusters = mftClusters;
382 sources[1].patterns = mftPatterns;
384 sources[1].dictionary = &dict();
385 sources[1].layerToSurface = mftMapping;
387 sources[1].setDecoder(mftDecoder);
390 configureFrame(frame, layout);
391 BOOST_REQUIRE_NO_THROW(test::loadTimeFrameSources(frame,
sources, layout.getCatalog(), {0, 0}));
396 const std::array<std::vector<int>, 4> expectedBoundaries{{{0, 1, 1, 1}, {0, 1, 1, 2}, {0, 1}, {0, 0}}};
397 for (
int surface = 0; surface < 4; ++surface) {
399 BOOST_CHECK_EQUAL_COLLECTIONS(boundaries.begin(), boundaries.end(), expectedBoundaries[surface].begin(), expectedBoundaries[surface].end());
404 sources[1].layerToSurface = firstMFTSurface;
405 BOOST_CHECK_THROW(test::loadTimeFrameSources(frame,
sources, layout.getCatalog(), {0, 0}), std::runtime_error);
411 const auto layout = makeCombinedLayout();
412 BOOST_REQUIRE(layout.valid());
416 const auto patternsA = makePatternBytes(clustersA.size());
417 const auto patternsB = makePatternBytes(clustersB.size());
418 const std::vector<ROFRecord> rofsA{
ROFRecord{{0, 0}, 0, 0, 1}};
419 const std::vector<ROFRecord> rofsB{
ROFRecord{{0, 0}, 0, 0, 1}};
421 FakeClusterDecoder decoderA{o2::detectors::DetID::ITS, {0},
false};
422 FakeClusterDecoder decoderB{o2::detectors::DetID::ITS, {0},
false};
424 std::array<test::TestClusterSourceInput, 2>
sources{};
426 sources[0].detector = o2::detectors::DetID::ITS;
427 sources[0].clusters = clustersA;
428 sources[0].patterns = patternsA;
430 sources[0].dictionary = &dict();
431 sources[0].layerToSurface = itsLayerToSurface;
433 sources[0].setDecoder(decoderA);
436 sources[1].detector = o2::detectors::DetID::ITS;
437 sources[1].clusters = clustersB;
438 sources[1].patterns = patternsB;
440 sources[1].dictionary = &dict();
441 sources[1].layerToSurface = itsLayerToSurface;
443 sources[1].setDecoder(decoderB);
446 configureFrame(frame, layout);
447 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(
sources), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Invalid source-to-surface layer mapping") != std::string::npos; });
453 const auto layout = makeCombinedLayout();
454 BOOST_REQUIRE(layout.valid());
458 const auto patternsA = makePatternBytes(clustersA.size());
459 const auto patternsB = makePatternBytes(clustersB.size());
460 const std::vector<ROFRecord> rofsA{
ROFRecord{{0, 0}, 0, 0, 1}};
461 const std::vector<ROFRecord> rofsB{
ROFRecord{{0, 0}, 0, 0, 1}};
468 FakeClusterDecoder decoderA{o2::detectors::DetID::ITS, {0},
false};
469 FakeClusterDecoder decoderB{o2::detectors::DetID::ITS, {0},
false};
471 std::array<test::TestClusterSourceInput, 2>
sources{};
473 sources[0].detector = o2::detectors::DetID::ITS;
474 sources[0].clusters = clustersA;
475 sources[0].patterns = patternsA;
477 sources[0].dictionary = &dict();
479 sources[0].layerToSurface = firstITSSurface;
481 sources[0].setDecoder(decoderA);
484 sources[1].detector = o2::detectors::DetID::ITS;
485 sources[1].clusters = clustersB;
486 sources[1].patterns = patternsB;
488 sources[1].dictionary = &dict();
490 sources[1].layerToSurface = secondITSSurface;
492 sources[1].setDecoder(decoderB);
495 configureFrame(frame, layout);
496 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(
sources), {0, 0}));
499 BOOST_REQUIRE_EQUAL(onSurfaceZero.size(), 1u);
506 BOOST_REQUIRE_EQUAL(labelSpanA.size(), 1u);
507 BOOST_REQUIRE_EQUAL(labelSpanB.size(), 1u);
513 const auto layout = makeCombinedLayout();
514 BOOST_REQUIRE(layout.valid());
517 const auto patterns = makePatternBytes(
clusters.size());
518 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 1}};
523 FakeClusterDecoder decoder{o2::detectors::DetID::ITS, {0},
false};
526 src.detector = o2::detectors::DetID::ITS;
528 src.patterns = patterns;
530 src.dictionary = &dict();
532 src.layerToSurface = itsLayerToSurface;
534 src.setDecoder(decoder);
537 configureFrame(frame, layout);
538 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0}));
540 constexpr uint32_t clusterId = 0;
542 BOOST_REQUIRE_EQUAL(labelPlain.size(), 1u);
551 const auto layout = makeCombinedLayout();
552 BOOST_REQUIRE(layout.valid());
555 const std::vector<CompClusterExt> clustersA{
559 const auto patternsA = makePatternBytes(clustersA.size());
560 const std::vector<ROFRecord> rofsA{
566 const auto patternsB = makePatternBytes(clustersB.size());
567 const std::vector<ROFRecord> rofsB{
ROFRecord{{0, 0}, 0, 0, 1}};
569 FakeClusterDecoder decoderA{o2::detectors::DetID::ITS, {0},
false};
570 FakeClusterDecoder decoderB{o2::detectors::DetID::ITS, {0},
false};
572 std::array<test::TestClusterSourceInput, 2>
sources{};
574 sources[0].detector = o2::detectors::DetID::ITS;
575 sources[0].clusters = clustersA;
576 sources[0].patterns = patternsA;
578 sources[0].dictionary = &dict();
579 sources[0].layerToSurface = firstITSSurface;
581 sources[0].setDecoder(decoderA);
584 sources[1].detector = o2::detectors::DetID::ITS;
585 sources[1].clusters = clustersB;
586 sources[1].patterns = patternsB;
588 sources[1].dictionary = &dict();
589 sources[1].layerToSurface = secondITSSurface;
591 sources[1].setDecoder(decoderB);
594 configureFrame(frame, layout);
595 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(
sources), {0, 0}));
604 const auto layout = makeCombinedLayout();
605 BOOST_REQUIRE(layout.valid());
609 const auto patternsA = makePatternBytes(clustersA.size());
610 const auto patternsB = makePatternBytes(clustersB.size());
613 const std::vector<ROFRecord> rofsA{
ROFRecord{{0, 0}, 0, 0, 1}};
614 const std::vector<ROFRecord> rofsB{
ROFRecord{{30, 0}, 0, 0, 1}};
617 const auto patternsC = makePatternBytes(clustersC.size());
618 const std::vector<ROFRecord> rofsC{
ROFRecord{{1000, 0}, 0, 0, 1}};
620 FakeClusterDecoder decoderA{o2::detectors::DetID::ITS, {0},
false};
621 FakeClusterDecoder decoderB{o2::detectors::DetID::ITS, {0},
false};
622 FakeClusterDecoder decoderC{o2::detectors::DetID::MFT, {0},
true};
624 std::array<test::TestClusterSourceInput, 3>
sources{};
626 sources[0].detector = o2::detectors::DetID::ITS;
627 sources[0].clusters = clustersA;
628 sources[0].patterns = patternsA;
630 sources[0].dictionary = &dict();
631 sources[0].layerToSurface = firstITSSurface;
633 sources[0].setDecoder(decoderA);
636 sources[1].detector = o2::detectors::DetID::ITS;
637 sources[1].clusters = clustersB;
638 sources[1].patterns = patternsB;
640 sources[1].dictionary = &dict();
641 sources[1].layerToSurface = secondITSSurface;
643 sources[1].setDecoder(decoderB);
646 sources[2].detector = o2::detectors::DetID::MFT;
647 sources[2].clusters = clustersC;
648 sources[2].patterns = patternsC;
650 sources[2].dictionary = &dict();
651 sources[2].layerToSurface = firstMFTSurface;
653 sources[2].setDecoder(decoderC);
656 configureFrame(frame, layout);
657 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(
sources), {0, 0}));
672 const auto layout = makeCombinedLayout();
673 BOOST_REQUIRE(layout.valid());
675 const std::vector<CompClusterExt> continuousClusters{
679 const auto continuousPatterns = makePatternBytes(continuousClusters.size());
680 const std::vector<ROFRecord> continuousRofs{
684 constexpr uint32_t continuousRofLength = 40;
686 const std::vector<CompClusterExt> triggeredClusters{
690 const auto triggeredPatterns = makePatternBytes(triggeredClusters.size());
692 const std::vector<ROFRecord> triggeredRofs{
696 constexpr uint32_t triggeredRofLength = 4;
698 FakeClusterDecoder continuousDecoder{o2::detectors::DetID::ITS, {0},
false};
699 FakeClusterDecoder triggeredDecoder{o2::detectors::DetID::ITS, {0},
false};
701 std::array<test::TestClusterSourceInput, 2>
sources{};
703 sources[0].detector = o2::detectors::DetID::ITS;
704 sources[0].clusters = continuousClusters;
705 sources[0].patterns = continuousPatterns;
706 sources[0].rofs = continuousRofs;
707 sources[0].dictionary = &dict();
708 sources[0].layerToSurface = firstITSSurface;
710 sources[0].setDecoder(continuousDecoder);
713 sources[1].detector = o2::detectors::DetID::ITS;
714 sources[1].clusters = triggeredClusters;
715 sources[1].patterns = triggeredPatterns;
716 sources[1].rofs = triggeredRofs;
717 sources[1].dictionary = &dict();
718 sources[1].layerToSurface = secondITSSurface;
720 sources[1].setDecoder(triggeredDecoder);
723 configureFrame(frame, layout);
724 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(
sources), {0, 0}));
731 const auto layout = makeCombinedLayout();
732 BOOST_REQUIRE(layout.valid());
734 const std::vector<CompClusterExt> clustersA{
737 const std::vector<CompClusterExt> clustersB{
740 const auto patternsA = makePatternBytes(clustersA.size());
741 const auto patternsB = makePatternBytes(clustersB.size());
742 const std::vector<ROFRecord> rofsA{
ROFRecord{{0, 0}, 0, 0, 2}};
743 const std::vector<ROFRecord> rofsB{
ROFRecord{{0, 0}, 0, 0, 2}};
745 FakeClusterDecoder decoderA{o2::detectors::DetID::ITS, {0},
false};
746 FakeClusterDecoder decoderB{o2::detectors::DetID::ITS, {0},
false};
748 std::array<test::TestClusterSourceInput, 2>
sources{};
750 sources[0].detector = o2::detectors::DetID::ITS;
751 sources[0].clusters = clustersA;
752 sources[0].patterns = patternsA;
754 sources[0].dictionary = &dict();
755 sources[0].layerToSurface = firstITSSurface;
757 sources[0].setDecoder(decoderA);
760 sources[1].detector = o2::detectors::DetID::ITS;
761 sources[1].clusters = clustersB;
762 sources[1].patterns = patternsB;
764 sources[1].dictionary = &dict();
765 sources[1].layerToSurface = secondITSSurface;
767 sources[1].setDecoder(decoderB);
770 configureFrame(frame, layout);
771 std::vector<std::vector<uint32_t>> clusterSizesBySurface;
772 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(
sources), {0, 0},
773 nullptr, &clusterSizesBySurface));
785 const auto layout = makeCombinedLayout();
786 const std::vector<CompClusterExt>
clusters{
789 const std::vector<unsigned char> patterns{onePixelPattern.begin(), onePixelPattern.end()};
790 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 2}};
791 PatternContractDecoder decoder;
795 src.detector = o2::detectors::DetID::ITS;
797 src.patterns = patterns;
799 src.dictionary = &dict();
800 src.layerToSurface = itsLayerToSurface;
802 src.setDecoder(decoder);
805 configureFrame(frame, layout);
806 std::vector<std::vector<uint32_t>> clusterSizesBySurface;
807 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0},
808 nullptr, &clusterSizesBySurface));
816 const auto layout = makeCombinedLayout();
817 PatternContractDecoder decoder;
819 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 1}};
821 auto makeSource = [&](gsl::span<const unsigned char> patterns) {
824 src.detector = o2::detectors::DetID::ITS;
826 src.patterns = patterns;
828 src.dictionary = &dict();
829 src.layerToSurface = itsLayerToSurface;
831 src.setDecoder(decoder);
835 const std::vector<unsigned char> exact{onePixelPattern.begin(), onePixelPattern.end()};
836 auto exactSource = makeSource(exact);
838 configureFrame(frame, layout);
839 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&exactSource, 1), {0, 0}));
841 const std::vector<unsigned char> trailing{1, 1, 0x80, 0xff};
842 auto trailingSource = makeSource(trailing);
843 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&trailingSource, 1), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Trailing cluster pattern data") != std::string::npos; });
847 auto missingDictionarySource = makeSource(exact);
848 missingDictionarySource.dictionary =
nullptr;
849 BOOST_CHECK_EXCEPTION(test::loadSources(
850 frame, layout.getCatalog(),
851 gsl::span<const test::TestClusterSourceInput>(&missingDictionarySource, 1), {0, 0}),
852 std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Cluster dictionary is not available") != std::string::npos; });
858 const auto layout = makeCombinedLayout();
860 configureFrame(frame, layout);
865 source.patterns = onePixelPattern;
866 source.layerToSurface = itsLayerToSurface;
868 std::runtime_error, [](
const std::runtime_error& error) {
869 return std::string(error.what()).find(
"Cluster dictionary is not available source=0") != std::string::npos;
875 const auto layout = makeCombinedLayout();
876 BOOST_REQUIRE(layout.valid());
879 const auto patterns = makePatternBytes(
clusters.size());
880 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 1}};
882 FakeClusterDecoder decoder{o2::detectors::DetID::ITS, {0},
false};
885 src.detector = o2::detectors::DetID::ITS;
887 src.patterns = patterns;
889 src.dictionary = &dict();
890 src.labels =
nullptr;
891 src.layerToSurface = itsLayerToSurface;
893 src.setDecoder(decoder);
896 configureFrame(frame, layout);
897 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0}));
905 const auto layout = makeCombinedLayout();
906 BOOST_REQUIRE(layout.valid());
908 const auto patterns = makePatternBytes(
clusters.size());
909 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 1}};
910 FakeClusterDecoder decoderA{o2::detectors::DetID::ITS, {0},
false};
911 FakeClusterDecoder decoderB{o2::detectors::DetID::ITS, {0},
false};
916 src.detector = o2::detectors::DetID::ITS;
918 src.patterns = patterns;
920 src.dictionary = &dict();
921 src.layerToSurface = itsLayerToSurface;
923 src.setDecoder(decoder);
931 configureFrame(frame, layout);
932 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(
sources), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Source IDs must be dense") != std::string::npos; });
938 configureFrame(frame, layout);
939 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(
sources), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Duplicate source ID") != std::string::npos; });
943 std::array<test::TestClusterSourceInput, 1>
sources{makeSource(ClusterSourceId::invalid(), decoderA)};
945 configureFrame(frame, layout);
946 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(
sources), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Source IDs must be dense") != std::string::npos; });
952 const auto layout = makeCombinedLayout();
953 BOOST_REQUIRE(layout.valid());
954 const std::vector<CompClusterExt>
clusters{
957 const auto patterns = makePatternBytes(
clusters.size());
958 FakeClusterDecoder decoder{o2::detectors::DetID::ITS, {0},
false};
960 auto makeSrc = [&](
const std::vector<ROFRecord>& rofs) {
963 src.detector = o2::detectors::DetID::ITS;
965 src.patterns = patterns;
967 src.dictionary = &dict();
968 src.layerToSurface = itsLayerToSurface;
970 src.setDecoder(decoder);
976 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 5}};
977 auto src = makeSrc(rofs);
979 configureFrame(frame, layout);
980 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Invalid ROF cluster range") != std::string::npos; });
984 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 2},
ROFRecord{{40, 0}, 1, 1, 1}};
985 auto src = makeSrc(rofs);
987 configureFrame(frame, layout);
988 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Invalid ROF cluster range") != std::string::npos; });
992 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 1, 1}};
993 auto src = makeSrc(rofs);
995 configureFrame(frame, layout);
996 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Invalid ROF cluster range") != std::string::npos; });
1002 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 1},
ROFRecord{{40, 0}, 1, 2, 0}};
1003 auto src = makeSrc(rofs);
1005 configureFrame(frame, layout);
1006 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Invalid ROF cluster range") != std::string::npos; });
1011 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 1}};
1012 auto src = makeSrc(rofs);
1014 configureFrame(frame, layout);
1015 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Invalid ROF cluster range") != std::string::npos; });
1020 const std::vector<ROFRecord> rofs{};
1021 auto src = makeSrc(rofs);
1023 configureFrame(frame, layout);
1024 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Invalid ROF cluster range") != std::string::npos; });
1030 const auto layout = makeCombinedLayout();
1031 BOOST_REQUIRE(layout.valid());
1032 const std::vector<CompClusterExt>
clusters{};
1033 const std::vector<unsigned char> patterns{};
1034 const std::vector<ROFRecord> rofs{};
1035 FakeClusterDecoder decoder{o2::detectors::DetID::ITS, {0},
false};
1039 src.detector = o2::detectors::DetID::ITS;
1041 src.patterns = patterns;
1043 src.dictionary = &dict();
1044 src.layerToSurface = itsLayerToSurface;
1046 src.setDecoder(decoder);
1049 configureFrame(frame, layout);
1050 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0}));
1056 const auto layout = makeCombinedLayout();
1057 BOOST_REQUIRE(layout.valid());
1059 const auto patterns = makePatternBytes(
clusters.size());
1060 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 1}};
1061 FakeClusterDecoder decoder{o2::detectors::DetID::ITS, {-1, 1},
false};
1065 src.detector = o2::detectors::DetID::ITS;
1067 src.patterns = patterns;
1069 src.dictionary = &dict();
1070 src.layerToSurface = gsl::span<const LayerId>(itsLayerToSurface.data(), 1);
1072 src.setDecoder(decoder);
1075 configureFrame(frame, layout);
1076 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Invalid source-to-surface layer mapping") != std::string::npos; });
1081 const auto layout = makeCombinedLayout();
1082 BOOST_REQUIRE(layout.valid());
1084 const auto patterns = makePatternBytes(
clusters.size());
1085 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 1}};
1086 FakeClusterDecoder decoder{o2::detectors::DetID::ITS, {0},
false};
1090 src.detector = o2::detectors::DetID::ITS;
1092 src.patterns = patterns;
1094 src.dictionary = &dict();
1096 const std::array<LayerId, 1> wrongMapping{
LayerId{2}};
1097 src.layerToSurface = wrongMapping;
1099 src.setDecoder(decoder);
1102 configureFrame(frame, layout);
1103 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Source detector does not match its surface") != std::string::npos; });
1110 const auto layout = makeCombinedLayout();
1111 BOOST_REQUIRE(layout.valid());
1113 const auto patterns = makePatternBytes(
clusters.size());
1114 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 1}};
1116 const std::array<Corruption, 2> corruptions{
1117 Corruption::NegativeLayer, Corruption::LayerOutOfRange};
1118 for (
const auto corruption : corruptions) {
1119 FakeClusterDecoder decoder{o2::detectors::DetID::ITS, {0},
false, corruption};
1122 src.detector = o2::detectors::DetID::ITS;
1124 src.patterns = patterns;
1126 src.dictionary = &dict();
1127 src.layerToSurface = itsLayerToSurface;
1129 src.setDecoder(decoder);
1132 configureFrame(frame, layout);
1133 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&
src, 1), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Invalid source-to-surface layer mapping") != std::string::npos; });
1140 const auto layout = makeCombinedLayout();
1141 BOOST_REQUIRE(layout.valid());
1144 const auto patterns = makePatternBytes(
clusters.size());
1145 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 1}};
1146 FakeClusterDecoder decoder{o2::detectors::DetID::ITS, {0},
false};
1150 goodSrc.
detector = o2::detectors::DetID::ITS;
1153 goodSrc.
rofs = rofs;
1160 configureFrame(frame, layout);
1161 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&goodSrc, 1), {0, 0}));
1165 std::array<test::TestClusterSourceInput, 2> badSources{goodSrc, goodSrc};
1166 BOOST_CHECK_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(badSources), {0, 0}), std::runtime_error);
1175 const auto layout = makeCombinedLayout();
1176 BOOST_REQUIRE(layout.valid());
1179 const auto patterns = makePatternBytes(
clusters.size());
1180 const std::vector<ROFRecord> rofs{
ROFRecord{{0, 0}, 0, 0, 1}};
1183 FakeClusterDecoder decoder{o2::detectors::DetID::ITS, {0},
false};
1187 goodSrc.
detector = o2::detectors::DetID::ITS;
1190 goodSrc.
rofs = rofs;
1198 configureFrame(frame, layout);
1199 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(&goodSrc, 1), {0, 0}));
1204 FakeClusterDecoder decoderA{o2::detectors::DetID::ITS, {0},
false};
1205 FakeClusterDecoder decoderB{o2::detectors::DetID::MFT, {0},
true, Corruption::NegativeLayer};
1212 srcB.
detector = o2::detectors::DetID::MFT;
1217 const std::array<LayerId, 1> mapping{
LayerId{2}};
1222 std::array<test::TestClusterSourceInput, 2>
sources{srcA, srcB};
1223 BOOST_CHECK_EXCEPTION(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>(
sources), {0, 0}), std::runtime_error, [](
const std::runtime_error& error) { return std::string(error.what()).find(
"Invalid source-to-surface layer mapping") != std::string::npos; });
1240 const auto layout = makeCombinedLayout();
1241 BOOST_REQUIRE(layout.valid());
1242 configureFrame(frame, layout);
1243 BOOST_REQUIRE_NO_THROW(test::loadSources(frame, layout.getCatalog(), gsl::span<const test::TestClusterSourceInput>{}, {0, 0}));
1258 BOOST_CHECK_EXCEPTION(test::loadSources(frame, emptyCatalog, gsl::span<const test::TestClusterSourceInput>{}, {0, 0}), std::runtime_error, [](
const std::runtime_error& error) {
return std::string(error.what()).find(
"TimeFrame is not configured") != std::string::npos; });
1267 configureFrame(frame, makeCombinedLayout());
1272 const std::array<RuntimeROFTableEntry, 4>
entries{{{0, 2}, {0, 3}, {0, 5}, {0, 7}}};
1273 const std::array<RuntimeROFTableEntry, 2> itsIndices{{{0, 1}, {1, 1}}};
1274 const std::array<RuntimeROFTableEntry, 2> mftIndices{{{2, 1}, {3, 1}}};
1280 const std::array<int, 2> boundaries{0, 0};
Definition of the ITSMFT compact cluster.
Passive common TimeFrame owner.
std::vector< long > entries
std::vector< o2::MCCompLabel > labels
Definition of a container to keep Monte Carlo truth external to simulation objects.
int ID
Detector identifiers: continuous, starting from 0.
UShort_t getSensorID() const
UShort_t getPatternID() const
static constexpr unsigned short InvalidPatternID
SurfaceCatalogView getSurfaceCatalog() const noexcept
bool valid() const noexcept
GLsizei GLsizei GLchar * source
GLenum GLuint GLint GLint layer
constexpr float DefClusError2Col
ClusterData< T > extractClusterData(const CompClusterExt &c, gsl::span< const unsigned char >::iterator &patterns, const TopologyDictionary *dict)
constexpr float DefClusError2Row
void loadTimeFrameSources(TimeFrame &, gsl::span< const ClusterSourceInput >, SurfaceCatalogView, std::vector< std::vector< uint32_t > > *externalIndicesBySurface=nullptr, std::vector< std::vector< uint32_t > > *clusterSizesBySurface=nullptr)
BOOST_AUTO_TEST_CASE(Cluster_messageable)
Marks an empty item in the context.
RuntimeROFVertexLookupView vertexLookup
void setROFClusters(std::size_t position, gsl::span< const int > boundaries)
gsl::span< const int > getROFrameClusters(int layer) const
void resetTimeFrame() noexcept
int getNrof(int layer) const
void setROFViews(RuntimeROFViews views) noexcept
std::size_t getTotalMeasurements() const noexcept
gsl::span< const o2::MCCompLabel > getLabels(LayerId layer, uint32_t clusterId) const
uint32_t getNMeasurementSurfaces() const noexcept
int getROFLocalLayer(int layer) const noexcept
const SurfaceMeasurement * getSurfaceMeasurement(LayerId layer, uint32_t clusterId) const noexcept
int getMaxVerticesPerROF() const noexcept
gsl::span< const GlobalMeasurement > getGlobalMeasurements(LayerId surface) const
int getClusterROF(int layer, int cluster) const
bool configure(DetectorConfiguration &&layout, std::size_t maxEdges, std::size_t maxCells, std::shared_ptr< BoundedMemoryResource > memoryPool)
coder decode(ctfImage, triggersD, clustersD)
std::vector< Cluster > clusters
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())
std::array< uint16_t, 5 > pattern