51#define BOOST_TEST_MODULE ITSMFT Tracker failure contract
52#define BOOST_TEST_MAIN
53#define BOOST_TEST_DYN_LINK
55#include <boost/test/unit_test.hpp>
64#include <oneapi/tbb/task_arena.h>
66#include <TGeoGlobalMagField.h>
96class LegacyLikeDecoder
103 gsl::span<const unsigned char>::iterator& patterns,
111 decoded.global = {
static_cast<float>(sensorID) * 10.f,
static_cast<float>(cluster.
getRow()),
static_cast<float>(cluster.
getCol())};
112 decoded.cylinderFrame = {
static_cast<float>(sensorID) + 100.f,
static_cast<float>(cluster.
getRow()) + 1.f,
static_cast<float>(cluster.
getCol()) + 2.f, 0.01f * sensorID};
113 decoded.rowColumnCovariance = {clusterData.sig2Row, 0.f, clusterData.sig2Col};
114 decoded.nPixels = clusterData.nPixels;
115 decoded.layer = sensorID;
144void ensureTrivialMagneticFieldIsSet()
146 static const bool done = [] {
148 TGeoGlobalMagField::Instance()->Lock();
154constexpr std::array<unsigned char, 3> onePixelPattern{1, 1, 0x80};
155constexpr std::array<unsigned char, 3> threePixelPattern{1, 3, 0xE0};
157std::vector<unsigned char> concatPatterns(std::initializer_list<gsl::span<const unsigned char>> parts)
159 std::vector<unsigned char> bytes;
160 for (
const auto& p : parts) {
161 bytes.insert(bytes.end(), p.begin(), p.end());
166std::vector<SurfaceDescriptor> makeITSTestCatalog()
168 std::vector<SurfaceDescriptor> surfaces;
171 surfaces.push_back(
SurfaceDescriptor{
i,
static_cast<uint8_t
>(o2::detectors::DetID::ITS), SurfaceKind::Cylinder});
172 surfaces.back().referenceCoordinate =
kITSSurfaces[
i].referenceCoordinate;
173 surfaces.back().chartRange = {-20.f, 20.f};
176 surfaces.back().material.xOverX0 = xOverX0;
182std::vector<LayerId> identitySurfaces(uint16_t nLayers)
184 std::vector<LayerId> mapping;
185 mapping.reserve(nLayers);
186 for (uint16_t
i = 0;
i < nLayers; ++
i) {
193 std::vector<CompClusterExt>
clusters;
194 std::vector<unsigned char> patterns;
195 std::vector<ROFRecord> rofs;
211 f.patterns = concatPatterns({onePixelPattern, threePixelPattern, onePixelPattern, threePixelPattern});
216 for (uint32_t
i = 0;
i <
f.clusters.size(); ++
i) {
222std::vector<TrackingParameters> makeOneIterationITSParams(
bool dropTFUponFailure,
size_t maxMemory = std::numeric_limits<size_t>::max())
224 std::vector<TrackingParameters>
params(1);
225 params[0] = test::makeTestTrackingParameters(o2::detectors::DetID::ITS);
226 params[0].DropTFUponFailure = dropTFUponFailure;
227 params[0].MaxMemory = maxMemory;
235std::vector<TrackingParameters> makeTwoIterationITSParams(
bool dropTFUponFailure)
237 std::vector<TrackingParameters>
params(2);
238 params[0] = test::makeTestTrackingParameters(o2::detectors::DetID::ITS);
239 params[1] = test::makeTestTrackingParameters(o2::detectors::DetID::ITS);
242 p.DropTFUponFailure = dropTFUponFailure;
250 explicit Rig(
bool dropTFUponFailure,
size_t maxMemory = std::numeric_limits<size_t>::max())
251 : pool(std::make_shared<BoundedMemoryResource>()),
252 params(makeOneIterationITSParams(dropTFUponFailure, maxMemory)),
255 traits.setNThreads(1, arena);
260 void stageStaleState()
264 track.clusterRefEnd =
static_cast<uint32_t
>(frame.getTrackClusterIndices().size());
265 frame.getGenericTracks().push_back(track);
266 BOOST_REQUIRE(!frame.getGenericTracks().empty());
267 BOOST_REQUIRE(!frame.getTrackClusterIndices().empty());
270 std::shared_ptr<BoundedMemoryResource> pool;
271 std::vector<TrackingParameters>
params;
277 std::optional<o2::its::ROFOverlapTable<ITSNLayers>> rofTable;
278 std::optional<o2::its::ROFVertexLookupTable<ITSNLayers>> vertexTable;
279 std::optional<o2::its::ROFMaskTable<ITSNLayers>>
mask;
280 std::shared_ptr<tbb::task_arena> arena;
281 std::vector<SurfaceDescriptor> catalog;
284 void establishValidLayout()
286 catalog = makeITSTestCatalog();
287 const SurfaceCatalogView catalogView{catalog.data(),
static_cast<uint32_t
>(catalog.size())};
289 configuration.
catalog = catalogView;
291 const auto orderedSurfaces = identitySurfaces(
ITSNLayers);
312 LegacyLikeDecoder decoder{o2::detectors::DetID::ITS};
316 const auto layerMapping = identitySurfaces(
ITSNLayers);
317 BOOST_REQUIRE_NO_THROW(test::loadTimeFrameSource(frame, decoder,
origin, timing,
f.clusters,
f.patterns,
f.rofs, &dict(),
318 f.labels.getIndexedSize() > 0 ? &
f.labels :
nullptr, o2::detectors::DetID::ITS,
319 gsl::span<const LayerId>{layerMapping}, layout.getSurfaceCatalog()));
334 timing2.
mNROFsTF =
static_cast<unsigned int>(
f.rofs.size());
335 timing2.mROFLength = 40;
337 for (
int iLayer = 0; iLayer <
ITSNLayers; ++iLayer) {
338 rofTable->defineLayer(iLayer, timing2);
341 vertexTable.emplace();
342 for (
int iLayer = 0; iLayer <
ITSNLayers; ++iLayer) {
343 vertexTable->defineLayer(iLayer, timing2);
347 mask.emplace(*rofTable);
349 for (
int iLayer = 0; iLayer <
ITSNLayers; ++iLayer) {
350 mask->setROFsEnabled(iLayer, 0, timing2.mNROFsTF, 1);
357 void forceMemoryLimitAtCurrentUsage()
359 const auto used = pool->getUsedMemory();
360 pool->setMaxMemory(used);
363 void restoreUnboundedMemory()
365 pool->setMaxMemory(std::numeric_limits<size_t>::max());
380 ensureTrivialMagneticFieldIsSet();
381 for (
const bool dropFlag : {
false,
true}) {
383 rig.establishValidLayout();
384 rig.loadSource(makeFixture());
385 rig.stageStaleState();
386 auto measurements = rig.frame.getGlobalMeasurements(
LayerId{0});
387 BOOST_REQUIRE(!measurements.empty());
388 measurements.front().clusterId = std::numeric_limits<uint32_t>::max();
390 BOOST_CHECK_THROW(rig.tracker.run(rig.frame, rig.traits), std::invalid_argument);
393 BOOST_CHECK(rig.frame.getTrackClusterIndices().empty());
400 rig.establishValidLayout();
401 rig.loadSource(makeFixture());
402 BOOST_REQUIRE(rig.frame.getTotalMeasurements() > 0u);
404 rig.forceMemoryLimitAtCurrentUsage();
406 const auto result = rig.tracker.run(rig.frame, rig.traits);
416 rig.establishValidLayout();
417 rig.loadSource(makeFixture());
418 BOOST_REQUIRE(rig.frame.getTotalMeasurements() > 0u);
420 rig.forceMemoryLimitAtCurrentUsage();
439 for (
const bool dropFlag : {
false,
true}) {
441 rig.params[0].RowBins = 0;
442 rig.catalog = makeITSTestCatalog();
443 const auto orderedSurfaces = identitySurfaces(
ITSNLayers);
445 configuration.
catalog = {rig.catalog.data(),
static_cast<uint32_t
>(rig.catalog.size())};
448 const auto result = rig.tracker.initialize(rig.frame, configuration);
456 for (
const bool dropFlag : {
false,
true}) {
458 rig.params = makeTwoIterationITSParams(dropFlag);
459 const auto validMinPt = rig.params[1].TrackletMinPt;
460 rig.params[1].TrackletMinPt = -1.f;
461 rig.catalog = makeITSTestCatalog();
463 configuration.
catalog = {rig.catalog.data(),
static_cast<uint32_t
>(rig.catalog.size())};
466 const auto result = rig.tracker.initialize(rig.frame, configuration);
470 BOOST_CHECK(rig.tracker.getIterationConfigurations().empty());
473 BOOST_REQUIRE(rig.tracker.initialize(rig.frame, configuration));
474 BOOST_REQUIRE(rig.tracker.isConfiguredFor(rig.frame));
475 BOOST_REQUIRE_EQUAL(rig.tracker.getIterationConfigurations().size(), 2u);
476 const auto* iterations = rig.tracker.getIterationConfigurations().data();
477 const auto* catalog = rig.frame.getDetectorConfiguration().getSurfaceCatalog().surfaces;
478 BOOST_CHECK(!rig.tracker.initialize(rig.frame, configuration));
479 BOOST_CHECK(rig.tracker.isConfiguredFor(rig.frame));
480 BOOST_CHECK(rig.tracker.getIterationConfigurations().data() == iterations);
481 BOOST_CHECK(rig.frame.getDetectorConfiguration().getSurfaceCatalog().surfaces == catalog);
489 ensureTrivialMagneticFieldIsSet();
491 rig.establishValidLayout();
492 rig.loadSource(emptyFixture());
493 BOOST_REQUIRE_EQUAL(rig.frame.getTotalMeasurements(), 0u);
499 BOOST_CHECK(rig.tracker.getRunStatistics().elapsedMs > 0.f);
505 ensureTrivialMagneticFieldIsSet();
506 for (
bool drop : {
false,
true}) {
508 rig.establishValidLayout();
509 rig.loadSource(emptyFixture());
510 BOOST_REQUIRE(rig.tracker.run(rig.frame, rig.traits));
511 BOOST_REQUIRE(rig.tracker.getRunStatistics().elapsedMs > 0.f);
512 BOOST_REQUIRE_EQUAL(rig.tracker.getRunStatistics().acceptedTrackCounts.size(), 1u);
514 rig.frame.resetTimeFrame();
515 rig.loadSource(makeFixture());
516 rig.forceMemoryLimitAtCurrentUsage();
518 BOOST_CHECK(!rig.tracker.run(rig.frame, rig.traits));
523 BOOST_CHECK(rig.tracker.getRunStatistics().acceptedTrackCounts.empty());
535 rig.establishValidLayout();
536 rig.loadSource(makeFixture());
537 rig.stageStaleState();
539 rig.forceMemoryLimitAtCurrentUsage();
540 const auto result = rig.tracker.run(rig.frame, rig.traits);
544 BOOST_CHECK(rig.frame.getTrackClusterIndices().empty());
551 ensureTrivialMagneticFieldIsSet();
553 rig.establishValidLayout();
554 rig.loadSource(makeFixture());
556 rig.forceMemoryLimitAtCurrentUsage();
557 const auto dropped = rig.tracker.run(rig.frame, rig.traits);
558 BOOST_REQUIRE(!dropped);
563 rig.restoreUnboundedMemory();
564 rig.loadSource(emptyFixture());
569 BOOST_CHECK(rig.tracker.getRunStatistics().elapsedMs > 0.f);
header::DataOrigin origin
Definition of the ITSMFT compact cluster.
Shared CA tracking configuration for ITS and MFT.
Passive common TimeFrame owner.
std::vector< o2::MCCompLabel > labels
Definition of a container to keep Monte Carlo truth external to simulation objects.
Definition of the MagF class.
Runtime-plan-owned, detector-neutral CA workspace.
int ID
Detector identifiers: continuous, starting from 0.
UShort_t getSensorID() const
static constexpr unsigned short InvalidPatternID
std::size_t size() const noexcept
bool initialize(TimeFrame &frame, const TrackerInitialization &configuration)
Shared CA tracker traits: same ITS-style tracklet/cell/road logic; MFT uses x-y LUT and forward refit...
GLenum const GLfloat * params
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
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, ITSNLayers > kITSSurfaces
constexpr int ITSNLayers
ITS CA layer count.
BOOST_AUTO_TEST_CASE(Cluster_messageable)
std::vector< IterationParameters > iterations
const DetectorConfiguration & getDetectorConfiguration() const noexcept
void setROFViews(RuntimeROFViews views) noexcept
SurfaceCatalogView catalog
std::shared_ptr< BoundedMemoryResource > memoryPool
BOOST_CHECK_NO_THROW(algorithm::merge(target, other))
coder decode(ctfImage, triggersD, clustersD)
std::vector< Cluster > clusters
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())