12#define BOOST_TEST_MODULE ITSMFT CombinedTrackingComposition
13#define BOOST_TEST_MAIN
14#define BOOST_TEST_DYN_LINK
27#include <boost/test/unit_test.hpp>
29#include <oneapi/tbb/task_arena.h>
31#include <TGeoGlobalMagField.h>
58struct GenericTrackPublicationExport {
62 gsl::span<const LayerId> layerMapping;
65constexpr float Bz = 0.5f;
66constexpr std::array<unsigned char, 3> OnePixelPattern{1, 1, 0x80};
74void ensureTrivialMagneticFieldIsSet()
76 static const bool done = [] {
78 TGeoGlobalMagField::Instance()->Lock();
84std::vector<LayerId> ordered(uint16_t
first, uint16_t
count)
86 std::vector<LayerId>
result;
88 for (uint16_t
i = 0;
i <
count; ++
i) {
94class PrescribedDecoder
98 : mDetector{detector}, mKind{
kind}, mClusters{std::move(
clusters)}
104 gsl::span<const unsigned char>::iterator& patterns,
106 uint32_t externalIndex)
const
110 if (externalIndex >= mClusters.size()) {
113 auto decoded = mClusters[externalIndex];
114 decoded.
nPixels = clusterData.nPixels;
122 std::vector<DecodedCluster> mClusters;
129 cluster.rowColumnCovariance = {1.e-2f, 0.f, 1.e-2f};
130 cluster.layer =
layer;
137 cluster.
global = {radius * std::cos(phi), radius * std::sin(phi), radius * tanLambda};
138 cluster.cylinderFrame = {cluster.global.
x, cluster.global.y, cluster.global.z, 0.f};
139 cluster.rowColumnCovariance = {1.e-2f, 0.f, 1.e-2f};
140 cluster.layer =
layer;
155std::vector<DecodedCluster> buildItsHelixChainClusters(
const std::vector<float>& radii,
float bz,
float pt,
float phi0,
float tanl)
157 const float px = pt * std::cos(phi0);
158 const float py = pt * std::sin(phi0);
159 const float pz = pt * tanl;
160 o2::track::TrackPar seed(std::array<float, 3>{0.f, 0.f, 0.f}, std::array<float, 3>{px, py, pz}, 1,
true);
162 std::vector<DecodedCluster>
clusters;
170 const auto point = seed.getXYZGloAt(xAtR, bz, ok);
175 cluster.
global = {
static_cast<float>(point.X()),
static_cast<float>(point.Y()),
static_cast<float>(point.Z())};
176 cluster.cylinderFrame = {cluster.global.
x, cluster.global.y, cluster.global.z, 0.f};
177 cluster.rowColumnCovariance = {1.e-2f, 0.f, 1.e-2f};
178 cluster.layer =
static_cast<int>(
layer);
186 auto p = test::makeTestTrackingParameters(o2::detectors::DetID::ITS);
199 auto p = test::makeTestTrackingParameters(o2::detectors::DetID::MFT);
201 p.CreateArtefactLabels =
false;
210 const PrescribedDecoder& decoder, std::vector<CompClusterExt>& compactOut,
211 std::vector<unsigned char>& patternsOut, std::vector<ROFRecord>& rofsOut,
212 const std::vector<DecodedCluster>& decoded)
214 compactOut.reserve(decoded.size());
215 patternsOut.reserve(decoded.size() * OnePixelPattern.size());
216 for (
const auto& cluster : decoded) {
218 patternsOut.insert(patternsOut.end(), OnePixelPattern.begin(), OnePixelPattern.end());
220 rofsOut = {
ROFRecord{{100, 5}, 0, 0,
static_cast<int>(compactOut.size())}};
225 source.clusters = compactOut;
226 source.patterns = patternsOut;
228 source.dictionary = &dict();
229 source.layerToSurface = surfaces;
231 source.setDecoder(decoder);
239 const PrescribedDecoder& decoder)
244 source.dictionary = &dict();
245 source.layerToSurface = surfaces;
247 source.setDecoder(decoder);
256template <o2::detectors::DetID::ID DetId,
int NLayers>
257struct StandaloneRun {
259 std::vector<TrackingParameters>
params;
260 std::shared_ptr<BoundedMemoryResource> pool = std::make_shared<BoundedMemoryResource>();
263 std::shared_ptr<tbb::task_arena> arena;
265 std::vector<SurfaceDescriptor> catalog;
270 int rofLength = 40,
LayerMask holeLayers = {})
273 const auto orderedSurfaces = ordered(0, NLayers);
274 catalog.reserve(NLayers);
275 for (uint16_t
i = 0;
i < NLayers; ++
i) {
278 surface.referenceCoordinate =
kind == SurfaceKind::Cylinder
282 surface.material.xOverX0 = xOverX0;
284 catalog.push_back(surface);
286 const SurfaceCatalogView catalogView{catalog.data(),
static_cast<uint32_t
>(catalog.size())};
288 configuration.
catalog = catalogView;
292 const auto configured = tracker.
initialize(frame, configuration);
293 BOOST_REQUIRE(configured);
294 scratch = &frame.getScratch();
298 std::vector<CompClusterExt> compact;
299 std::vector<unsigned char> patterns;
300 for (
const auto& cluster : decoded) {
302 patterns.insert(patterns.end(), OnePixelPattern.begin(), OnePixelPattern.end());
304 const std::vector<ROFRecord> rofs{
ROFRecord{{100, 5}, 0, 0,
static_cast<int>(compact.size())}};
305 PrescribedDecoder decoder{det,
kind, decoded};
306 const auto layerMapping = ordered(0, NLayers);
308 compact, patterns, rofs, &dict(),
nullptr, det,
309 gsl::span<const LayerId>{layerMapping},
310 frame.getDetectorConfiguration().getSurfaceCatalog());
314 layerTiming.mROFLength = rofLength;
317 rofTable.defineLayer(
layer, layerTiming);
322 vtxTable.defineLayer(
layer, layerTiming);
330 frame.setROFViews(
RuntimeROFViews{rofTable.getView(), vtxTable.getView(),
mask.getView(), {}});
331 success = tracker.
run(frame, traits);
341struct CombinedTrackingComposer {
344 size_t nITSTracks{0};
345 size_t nMFTTracks{0};
346 bool exceptionThrown{
false};
351 std::optional<o2::its::LayerTiming> itsClock;
352 std::optional<o2::its::LayerTiming> mftClock;
353 bool publicationValid =
false;
355 CombinedTrackingComposer(std::vector<TrackingParameters> itsParams, std::vector<TrackingParameters> mftParams)
356 : plan(std::move(itsParams), std::move(mftParams))
365 void setBz(
float bz) { plan.
setBz(bz); }
368 void clearPublicationSidecars()
noexcept
372 void invalidatePublication()
noexcept
376 publicationValid =
false;
378 void markPublicationValid()
noexcept
382 publicationValid =
true;
384 std::optional<GenericTrackPublicationExport> getITSPublicationExport()
const
386 if (!publicationValid || !itsClock) {
389 return GenericTrackPublicationExport{o2::detectors::DetID::ITS,
ClusterSourceId{0}, *itsClock,
392 std::optional<GenericTrackPublicationExport> getMFTPublicationExport()
const
394 if (!publicationValid || !mftClock) {
397 return GenericTrackPublicationExport{o2::detectors::DetID::MFT,
ClusterSourceId{1}, *mftClock,
403 invalidatePublication();
404 clearPublicationSidecars();
407 auto itsInput = itsSource;
408 auto mftInput = mftSource;
413 const std::array<test::TestClusterSourceInput, 2>
sources{itsInput, mftInput};
414 test::loadTimeFrameSources(*frame, gsl::span<const test::TestClusterSourceInput>{
sources}, plan.
catalogView(),
origin);
415 }
catch (
const std::runtime_error&) {
418 invalidatePublication();
419 return {
false, 0, 0,
true};
423 const auto itsResult = plan.
runITS();
427 invalidatePublication();
428 return {itsResult, 0, 0};
430 const auto mftResult = plan.
runMFT();
434 invalidatePublication();
435 return {mftResult, 0, 0};
437 }
catch (
const std::exception&) {
440 invalidatePublication();
441 return {
false, 0, 0,
true};
444 markPublicationValid();
445 const auto countFor = [
this](
int first) {
446 return static_cast<size_t>(std::count_if(this->frame->
getGenericTracks().begin(), this->frame->getGenericTracks().end(),
447 [
first](
const auto& track) { return track.hitLayers.has(first); }));
449 return {
true, countFor(0), countFor(
ITSNLayers)};
455 gsl::span<const LayerId> getITSLayerMapping()
const noexcept {
return plan.
getITSLayerMapping(); }
456 gsl::span<const LayerId> getMFTLayerMapping()
const noexcept {
return plan.
getMFTLayerMapping(); }
461 return CombinedTrackingComposer{std::vector<TrackingParameters>{itsParams}, std::vector<TrackingParameters>{mftParams}};
464template <o2::detectors::DetID::ID DetId,
int NLayers>
467 ensureTrivialMagneticFieldIsSet();
468 BOOST_REQUIRE_EQUAL(
clusters.size(),
static_cast<size_t>(NLayers));
471 params.MinTrackLength = NLayers - 1;
475 for (
const int missingLayer : {3, NLayers - 1}) {
476 BOOST_TEST_CONTEXT(
"missing layer " << missingLayer)
479 incomplete.erase(incomplete.begin() + missingLayer);
480 StandaloneRun<DetId, NLayers> accepted{DetId,
kind,
params, incomplete, 40, allowedHoles};
481 BOOST_REQUIRE(accepted.success);
482 BOOST_REQUIRE_EQUAL(accepted.frame.getGenericTracks().size(), 1u);
483 BOOST_CHECK_EQUAL(accepted.frame.getGenericTracks().front().hitLayers.count(), NLayers - 1);
484 BOOST_CHECK(!accepted.frame.getGenericTracks().front().hitLayers.has(missingLayer));
487 stricter.MinTrackLength = NLayers;
488 StandaloneRun<DetId, NLayers> rejected{DetId,
kind, stricter, incomplete, 40, allowedHoles};
489 BOOST_REQUIRE(rejected.success);
490 BOOST_CHECK(rejected.frame.getGenericTracks().empty());
498 params.SeedingLayers = LayerMask::span(0, NLayers - 1) & ~allowedHoles;
500 BOOST_REQUIRE(sparseAccepted.success);
501 BOOST_REQUIRE_EQUAL(sparseAccepted.frame.getGenericTracks().size(), 1u);
502 BOOST_CHECK_EQUAL(sparseAccepted.frame.getGenericTracks().front().hitLayers.count(), NLayers - 1);
503 params.MinTrackLength = NLayers;
505 BOOST_REQUIRE(sparseRejected.success);
506 BOOST_CHECK(sparseRejected.frame.getGenericTracks().empty());
513 const auto params = makeItsParams();
514 std::vector<float> radii;
516 radii.push_back(surface.referenceCoordinate);
518 checkMinimumHitLayers<o2::detectors::DetID::ITS, ITSNLayers>(
519 SurfaceKind::Cylinder,
params, buildItsHelixChainClusters(radii, Bz, 1.f, 0.4f, 0.3f));
527 ensureTrivialMagneticFieldIsSet();
528 const auto itsSurfaces = ordered(0,
ITSNLayers);
530 const auto itsClusters = std::vector<DecodedCluster>{cylinderCluster(3.f, 0.2f, 0.1f, 0), cylinderCluster(4.f, 0.2f, 0.1f, 1)};
531 const auto mftClusters = std::vector<DecodedCluster>{diskCluster(1.f, 0.5f,
kMFTSurfaces[0].referenceCoordinate, 0), diskCluster(1.f, 0.5f,
kMFTSurfaces[1].referenceCoordinate, 1)};
533 PrescribedDecoder itsDecoder{o2::detectors::DetID::ITS, SurfaceKind::Cylinder, itsClusters};
534 PrescribedDecoder mftDecoder{o2::detectors::DetID::MFT, SurfaceKind::Disk, mftClusters};
535 std::vector<CompClusterExt> itsCompact, mftCompact;
536 std::vector<unsigned char> itsPatterns, mftPatterns;
537 std::vector<ROFRecord> itsRofs, mftRofs;
538 const auto itsSource = makeSource(
ClusterSourceId{0}, o2::detectors::DetID::ITS, itsSurfaces, itsDecoder, itsCompact, itsPatterns, itsRofs, itsClusters);
539 const auto mftSource = makeSource(
ClusterSourceId{1}, o2::detectors::DetID::MFT, mftSurfaces, mftDecoder, mftCompact, mftPatterns, mftRofs, mftClusters);
541 auto itsParams = makeItsParams();
542 auto mftParams = makeMftParams();
543 itsParams.MinTrackLength = 4;
544 mftParams.MinTrackLength = 5;
545 auto composer = makeComposer(itsParams, mftParams);
547 composer.adoptFrame(frame);
549 composer.setNThreads(1);
552 BOOST_REQUIRE_EQUAL(composer.plan.itsTracker().getIterationConfigurations().size(), 1u);
553 const auto& combined = composer.plan.itsTracker().getIterationConfigurations()[0].parameters;
557 BOOST_CHECK(combined.PassFlags == itsParams.PassFlags);
558 BOOST_REQUIRE(detector.indexTableConfigs.size() > 0);
559 BOOST_CHECK_EQUAL(detector.indexTableConfigs[0].getNcolBins(), itsParams.ColBins);
560 BOOST_CHECK_EQUAL(detector.indexTableConfigs[0].getNrowBins(), itsParams.RowBins);
562 BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(combined.Diamond), std::end(combined.Diamond),
563 std::begin(itsParams.Diamond), std::end(itsParams.Diamond));
564 BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(combined.DiamondCov), std::end(combined.DiamondCov),
565 std::begin(itsParams.DiamondCov), std::end(itsParams.DiamondCov));
571 BOOST_CHECK_EQUAL(combined.MaxChi2ClusterAttachment, itsParams.MaxChi2ClusterAttachment);
573 BOOST_CHECK_EQUAL_COLLECTIONS(combined.MinPt.begin(), combined.MinPt.end(), itsParams.MinPt.begin(), itsParams.MinPt.end());
576 BOOST_CHECK_EQUAL(combined.PerPrimaryVertexProcessing, itsParams.PerPrimaryVertexProcessing);
577 BOOST_CHECK_EQUAL(combined.AllowSharingFirstCluster, itsParams.AllowSharingFirstCluster);
578 BOOST_CHECK_EQUAL(combined.SharedClusterMaxDeltaPhi, itsParams.SharedClusterMaxDeltaPhi);
579 BOOST_CHECK_EQUAL(combined.SharedClusterMaxDeltaEta, itsParams.SharedClusterMaxDeltaEta);
580 BOOST_CHECK_EQUAL(combined.SharedClusterOppositeSign, itsParams.SharedClusterOppositeSign);
583 const auto checkConcatenated = [](
const auto& actual,
const auto& itsValues,
const auto& mftValues) {
584 BOOST_REQUIRE_EQUAL(actual.size(), itsValues.size() + mftValues.size());
585 BOOST_CHECK_EQUAL_COLLECTIONS(actual.begin(), actual.begin() + itsValues.size(), itsValues.begin(), itsValues.end());
586 BOOST_CHECK_EQUAL_COLLECTIONS(actual.begin() + itsValues.size(), actual.end(), mftValues.begin(), mftValues.end());
588 checkConcatenated(detector.addTimeError, itsParams.AddTimeError, mftParams.AddTimeError);
589 checkConcatenated(detector.layerResolution, itsParams.LayerResolution, mftParams.LayerResolution);
590 checkConcatenated(detector.systError2Row, itsParams.SystError2Row, mftParams.SystError2Row);
591 checkConcatenated(detector.systError2Col, itsParams.SystError2Col, mftParams.SystError2Col);
600 BOOST_REQUIRE(
result.success);
612 for (uint16_t edgeId = 0; edgeId < topology.nEdges; ++edgeId) {
613 const auto& edge = topology.getEdge(
EdgeId{edgeId});
614 const bool fromITS = edge.from.value() <
ITSNLayers;
615 const bool toITS = edge.to.value() <
ITSNLayers;
621 static_cast<int>(itsClusters.size() + mftClusters.size()));
630 ensureTrivialMagneticFieldIsSet();
631 const auto itsSurfaces = ordered(0,
ITSNLayers);
633 const auto itsClusters = std::vector<DecodedCluster>{cylinderCluster(3.f, 0.2f, 0.1f, 0), cylinderCluster(4.f, 0.2f, 0.1f, 1)};
634 const auto mftClusters = std::vector<DecodedCluster>{diskCluster(1.f, 0.5f,
kMFTSurfaces[0].referenceCoordinate, 0), diskCluster(1.f, 0.5f,
kMFTSurfaces[1].referenceCoordinate, 1)};
636 PrescribedDecoder itsDecoder{o2::detectors::DetID::ITS, SurfaceKind::Cylinder, itsClusters};
637 PrescribedDecoder mftDecoder{o2::detectors::DetID::MFT, SurfaceKind::Disk, mftClusters};
638 std::vector<CompClusterExt> itsCompact, mftCompact;
639 std::vector<unsigned char> itsPatterns, mftPatterns;
640 std::vector<ROFRecord> itsRofs, mftRofs;
641 const auto itsSource = makeSource(
ClusterSourceId{0}, o2::detectors::DetID::ITS, itsSurfaces, itsDecoder, itsCompact, itsPatterns, itsRofs, itsClusters);
642 auto mftSource = makeSource(
ClusterSourceId{1}, o2::detectors::DetID::MFT, mftSurfaces, mftDecoder, mftCompact, mftPatterns, mftRofs, mftClusters);
644 auto composer = makeComposer(makeItsParams(), makeMftParams());
646 composer.adoptFrame(frame);
648 composer.setNThreads(1);
654 BOOST_REQUIRE(
first.success);
655 BOOST_REQUIRE(composer.getITSPublicationExport().has_value());
656 BOOST_REQUIRE(composer.getMFTPublicationExport().has_value());
661 std::vector<ROFRecord> malformedMftRofs{
ROFRecord{{100, 5}, 0, 0, 1},
ROFRecord{{140, 5}, 0, 2, 1}};
662 mftSource.rofs = malformedMftRofs;
677 BOOST_CHECK(!composer.getITSPublicationExport().has_value());
678 BOOST_CHECK(!composer.getMFTPublicationExport().has_value());
683 ensureTrivialMagneticFieldIsSet();
684 const auto itsSurfaces = ordered(0,
ITSNLayers);
686 const auto itsClusters = std::vector<DecodedCluster>{cylinderCluster(3.f, 0.2f, 0.1f, 0), cylinderCluster(4.f, 0.2f, 0.1f, 1)};
687 const auto mftClusters = std::vector<DecodedCluster>{diskCluster(1.f, 0.5f,
kMFTSurfaces[0].referenceCoordinate, 0), diskCluster(1.f, 0.5f,
kMFTSurfaces[1].referenceCoordinate, 1)};
689 PrescribedDecoder itsDecoder{o2::detectors::DetID::ITS, SurfaceKind::Cylinder, itsClusters};
690 PrescribedDecoder mftDecoder{o2::detectors::DetID::MFT, SurfaceKind::Disk, mftClusters};
691 std::vector<CompClusterExt> itsCompact, mftCompact;
692 std::vector<unsigned char> itsPatterns, mftPatterns;
693 std::vector<ROFRecord> itsRofs, mftRofs;
694 const auto itsSource = makeSource(
ClusterSourceId{0}, o2::detectors::DetID::ITS, itsSurfaces, itsDecoder, itsCompact, itsPatterns, itsRofs, itsClusters);
695 const auto mftSource = makeSource(
ClusterSourceId{1}, o2::detectors::DetID::MFT, mftSurfaces, mftDecoder, mftCompact, mftPatterns, mftRofs, mftClusters);
700 auto itsParams = makeItsParams();
701 itsParams.MaxMemory = 1;
702 itsParams.DropTFUponFailure =
true;
704 auto composer = makeComposer(itsParams, makeMftParams());
706 composer.adoptFrame(frame);
708 composer.setNThreads(1);
716 BOOST_CHECK(!composer.getITSPublicationExport().has_value());
717 BOOST_CHECK(!composer.getMFTPublicationExport().has_value());
725struct MinimalFixture {
728 std::vector<DecodedCluster> itsClusters{cylinderCluster(3.f, 0.2f, 0.1f, 0), cylinderCluster(4.f, 0.2f, 0.1f, 1)};
729 std::vector<DecodedCluster> mftClusters{diskCluster(1.f, 0.5f,
kMFTSurfaces[0].referenceCoordinate, 0), diskCluster(1.f, 0.5f,
kMFTSurfaces[1].referenceCoordinate, 1)};
730 PrescribedDecoder itsDecoder{o2::detectors::DetID::ITS, SurfaceKind::Cylinder, itsClusters};
731 PrescribedDecoder mftDecoder{o2::detectors::DetID::MFT, SurfaceKind::Disk, mftClusters};
732 std::vector<CompClusterExt> itsCompact, mftCompact;
733 std::vector<unsigned char> itsPatterns, mftPatterns;
734 std::vector<ROFRecord> itsRofs, mftRofs;
740 itsSource = makeSource(
ClusterSourceId{0}, o2::detectors::DetID::ITS, itsSurfaces, itsDecoder, itsCompact, itsPatterns, itsRofs, itsClusters);
741 mftSource = makeSource(
ClusterSourceId{1}, o2::detectors::DetID::MFT, mftSurfaces, mftDecoder, mftCompact, mftPatterns, mftRofs, mftClusters);
748void makeRofGap(std::vector<ROFRecord>& rofs)
757 ensureTrivialMagneticFieldIsSet();
759 for (
const bool itsDropTF : {
true,
false}) {
760 MinimalFixture fixture;
761 makeRofGap(fixture.itsRofs);
762 fixture.itsSource.rofs = fixture.itsRofs;
764 auto itsParams = makeItsParams();
765 itsParams.DropTFUponFailure = itsDropTF;
766 auto composer = makeComposer(itsParams, makeMftParams());
768 composer.adoptFrame(frame);
770 composer.setNThreads(1);
774 BOOST_CHECK_MESSAGE(!
result.success,
"ITS DropTFUponFailure=" << itsDropTF);
781 BOOST_CHECK(!composer.getITSPublicationExport().has_value());
782 BOOST_CHECK(!composer.getMFTPublicationExport().has_value());
788 ensureTrivialMagneticFieldIsSet();
790 for (
const bool combinedDropTF : {
true,
false}) {
791 MinimalFixture fixture;
792 makeRofGap(fixture.mftRofs);
793 fixture.mftSource.rofs = fixture.mftRofs;
795 auto itsParams = makeItsParams();
796 itsParams.DropTFUponFailure = combinedDropTF;
797 auto mftParams = makeMftParams();
798 mftParams.DropTFUponFailure = !combinedDropTF;
799 auto composer = makeComposer(itsParams, mftParams);
801 composer.adoptFrame(frame);
803 composer.setNThreads(1);
807 BOOST_CHECK_MESSAGE(!
result.success,
"combined DropTFUponFailure=" << combinedDropTF);
811 BOOST_CHECK(!composer.getITSPublicationExport().has_value());
812 BOOST_CHECK(!composer.getMFTPublicationExport().has_value());
818 ensureTrivialMagneticFieldIsSet();
821 MinimalFixture fixture;
822 fixture.itsSource.dictionary =
nullptr;
824 auto itsParams = makeItsParams();
825 itsParams.DropTFUponFailure =
true;
826 auto composer = makeComposer(itsParams, makeMftParams());
828 composer.adoptFrame(frame);
830 composer.setNThreads(1);
836 BOOST_CHECK(!composer.getITSPublicationExport().has_value());
841 ensureTrivialMagneticFieldIsSet();
844 MinimalFixture fixture;
847 auto composer = makeComposer(makeItsParams(), makeMftParams());
849 composer.adoptFrame(frame);
851 composer.setNThreads(1);
857 BOOST_CHECK(!composer.getITSPublicationExport().has_value());
858 BOOST_CHECK(!composer.getMFTPublicationExport().has_value());
863 ensureTrivialMagneticFieldIsSet();
867 MinimalFixture fixture;
868 auto itsParams = makeItsParams();
869 itsParams.MaxMemory = 1;
871 auto composer = makeComposer(itsParams, makeMftParams());
873 composer.adoptFrame(frame);
875 composer.setNThreads(1);
883 BOOST_CHECK(!composer.getITSPublicationExport().has_value());
884 BOOST_CHECK(!composer.getMFTPublicationExport().has_value());
889 auto composer = makeComposer(makeItsParams(), makeMftParams());
891 composer.adoptFrame(frame);
895 const auto itsSurfacesBefore = composer.getITSLayerMapping();
896 const auto mftSurfacesBefore = composer.getMFTLayerMapping();
897 BOOST_REQUIRE_EQUAL(itsSurfacesBefore.size(),
static_cast<size_t>(
ITSNLayers));
898 BOOST_REQUIRE_EQUAL(mftSurfacesBefore.size(),
static_cast<size_t>(
MFTNLayers));
901 BOOST_CHECK(!composer.getITSPublicationExport().has_value());
902 BOOST_CHECK(!composer.getMFTPublicationExport().has_value());
906 ensureTrivialMagneticFieldIsSet();
907 MinimalFixture fixture;
908 makeRofGap(fixture.mftRofs);
909 fixture.mftSource.rofs = fixture.mftRofs;
911 composer.setNThreads(1);
913 BOOST_REQUIRE(!
failed.success);
914 BOOST_CHECK(composer.getITSLayerMapping().data() == itsSurfacesBefore.data());
915 BOOST_CHECK(composer.getMFTLayerMapping().data() == mftSurfacesBefore.data());
925 ensureTrivialMagneticFieldIsSet();
926 MinimalFixture fixture;
927 makeRofGap(fixture.itsRofs);
928 fixture.itsSource.rofs = fixture.itsRofs;
930 auto composer = makeComposer(makeItsParams(), makeMftParams());
932 composer.adoptFrame(frame);
934 composer.setNThreads(1);
937 BOOST_REQUIRE(!
result.success);
945 BOOST_CHECK(composer.getITSSharedClusterFlags().empty());
946 BOOST_CHECK(!composer.getITSPublicationExport().has_value());
947 BOOST_CHECK(!composer.getMFTPublicationExport().has_value());
952 auto init = test::makeCombinedConfiguration(makeItsParams(), makeMftParams());
953 std::vector<SurfaceDescriptor> catalog(init.catalog.surfaces, init.catalog.surfaces + init.catalog.nSurfaces);
954 catalog[0].material = {0.123f, 0.456f};
955 init.catalog = {catalog.data(),
static_cast<uint32_t
>(catalog.size())};
956 catalog[0].referenceCoordinate = 2.7f;
957 init.plan.execution = {123456789,
true};
958 init.plan.iterations.resize(3, init.plan.iterations.front());
959 init.plan.iterations[1].TrackletMinPt = 0.2f;
960 init.plan.iterations[2].TrackletMinPt = 0.1f;
963 BOOST_REQUIRE(tracker.
initialize(frame, init));
964 catalog[0].referenceCoordinate = 99.f;
965 catalog[0].material = {};
968 BOOST_CHECK_EQUAL(ownedCatalog.surfaces[0].material.arealDensityGPerCm2, 0.456f);
981 BOOST_CHECK(context.topology.catalog.surfaces == ownedCatalog.surfaces);
985 BOOST_REQUIRE_EQUAL(cache.configurationCount(), 2u);
989 BOOST_CHECK(cache[0].getCoordType() == IndexTableCoordType::PhiZ);
1001 BOOST_CHECK(detector.getSurfaceCatalog().surfaces == ownedCatalog.surfaces);
1006 auto detectorCopy = detector;
1007 BOOST_CHECK(detectorCopy.getSurfaceCatalog().surfaces != ownedCatalog.surfaces);
1008 BOOST_CHECK(&detectorCopy.indexTableConfigs[0] != &cache[0]);
1009 detectorCopy.layerResolution[0] = 42.f;
1010 auto movedDetector = std::move(detectorCopy);
1013 BOOST_CHECK_EQUAL(detector.layerResolution[0], init.plan.detector.LayerResolution[0]);
1020 auto init = test::makeCombinedConfiguration(makeItsParams(), makeMftParams());
1023 for (
const auto& boundaries : std::vector<std::vector<uint16_t>>{{}, {1}, {0, 0}, {0, 3, 2}, {0,
ITSNLayers +
MFTNLayers}}) {
1024 init.componentOffsets = boundaries;
1039 init.holeLayers = {};
1040 BOOST_REQUIRE(tracker.
initialize(frame, init));
1049 BOOST_REQUIRE(cache.
reset(catalog));
1067 auto init = test::makeCombinedConfiguration(makeItsParams(), makeMftParams());
1070 BOOST_REQUIRE(tracker.
initialize(frame, init));
1072 static_assert(std::is_same_v<
decltype(configuration.edgeIds()[0]),
EdgeId>);
1073 static_assert(std::is_same_v<
decltype(configuration.cellIds()[0]),
CellPathId>);
1074 for (
const auto id : configuration.edgeIds()) {
1075 BOOST_REQUIRE(configuration.getEdgeSlot(
id));
1078 for (
const auto id : configuration.cellIds()) {
1079 BOOST_REQUIRE(configuration.getCellSlot(
id));
1084 BOOST_CHECK(!configuration.getEdgeSlot(
EdgeId{static_cast<uint16_t>(configuration.topology.edges.size())}));
1085 BOOST_CHECK(!configuration.getCellSlot(
CellPathId{static_cast<uint16_t>(configuration.topology.paths.size())}));
header::DataOrigin origin
Definition of the ITSMFT compact cluster.
Shared CA tracking configuration for ITS and MFT.
Passive common TimeFrame owner.
Definition of the MagF class.
Runtime-plan-owned, detector-neutral CA workspace.
int ID
Detector identifiers: continuous, starting from 0.
static constexpr unsigned short InvalidPatternID
bool empty() const noexcept
IndexTableConfigurationSet indexTableConfigs
SurfaceCatalogView getSurfaceCatalog() const noexcept
float getRepresentativeRadius(LayerId id) const
std::size_t size() const noexcept
std::vector< float > layerResolution
size_t size() const noexcept
size_t configurationCount() const noexcept
bool reset(SurfaceCatalogView catalog) noexcept
void setNThreads(int n, std::shared_ptr< tbb::task_arena > &arena)
bool initialize(TimeFrame &frame, const TrackerInitialization &configuration)
const TrackingExecutionPolicy & getExecutionPolicy() const noexcept
bool run(TimeFrame &frame, TrackerTraits &traits)
gsl::span< const IterationConfiguration > getIterationConfigurations() const noexcept
RuntimeROFViews getITSROFViews() const noexcept
void clearPublicationSidecars() noexcept
void configureRofTables(const TestClusterSourceInput &itsSource, const TestClusterSourceInput &mftSource)
const TimeFrameScratch & getITSScratch() const noexcept
SurfaceCatalogView catalogView() const noexcept
gsl::span< const LayerId > getITSLayerMapping() const noexcept
gsl::span< const uint8_t > getITSSharedClusterFlags() const noexcept
void adoptFrame(TimeFrame &frame)
RuntimeROFViews getMFTROFViews() const noexcept
gsl::span< const LayerId > getMFTLayerMapping() const noexcept
void validateSources(const ClusterSourceInput &itsSource, const ClusterSourceInput &mftSource) const
const TimeFrameScratch & getMFTScratch() const noexcept
Shared CA tracker traits: same ITS-style tracklet/cell/road logic; MFT uses x-y LUT and forward refit...
GLsizei GLsizei GLchar * source
GLenum const GLfloat * params
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLenum GLuint GLint GLint layer
GLdouble GLdouble GLdouble z
ClusterData< T > extractClusterData(const CompClusterExt &c, gsl::span< const unsigned char >::iterator &patterns, const TopologyDictionary *dict)
TrackingPlan makeTrackingPlan(const TrackingParameters ¶meters)
constexpr std::array< SurfaceDescriptor, MFTNLayers > kMFTSurfaces
constexpr int MFTNLayers
MFT CA half-disk layer count.
constexpr std::array< SurfaceDescriptor, ITSNLayers > kITSSurfaces
constexpr int ITSNLayers
ITS CA layer count.
BOOST_AUTO_TEST_CASE(Cluster_messageable)
int process(po::variables_map &vm)
RuntimeROFOverlapView overlap
auto & getGenericTracks()
auto & getTrackClusterIndices()
void resetTimeFrame() noexcept
const DetectorConfiguration & getDetectorConfiguration() const noexcept
TimeFrameScratch & getScratch()
bool isConfigured() const noexcept
const auto & getIndexTableUtils() const
SurfaceCatalogView catalog
std::shared_ptr< BoundedMemoryResource > memoryPool
std::map< std::string, ID > expected
coder decode(ctfImage, triggersD, clustersD)
std::vector< Cluster > clusters
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())