@@ -485,16 +485,66 @@ BOOST_AUTO_TEST_CASE(DiskOnePassAndTwoPassProduceIdenticalTracklets)
485485 SurfaceKind::Disk, clusters, 1 );
486486 const auto parallel = runFixture<MFTNLayers>(o2::detectors::DetID::MFT , SurfaceKind::Disk,
487487 SurfaceKind::Disk, clusters, 4 );
488- const float sourceRadius = o2::gpu::CAMath::Hypot (1 .f , 0 .5f );
489- const float targetRadius = o2::gpu::CAMath::Hypot (targetX, targetY);
490- const float expectedTanLambda = (fromZ - toZ) / (sourceRadius - targetRadius);
488+ const float transverseChord = std::hypot (targetX - 1 .f , targetY - 0 .5f );
489+ const float expectedTanLambda = (toZ - fromZ) / transverseChord;
491490 const float expectedPhi = o2::gpu::CAMath::ATan2 (0 .5f - targetY, 1 .f - targetX);
492491 checkExactTracklet (serial, expectedTanLambda, expectedPhi);
493492 checkExactTracklet (parallel, expectedTanLambda, expectedPhi);
494493 checkSame (serial, parallel);
495494}
496495
497- BOOST_AUTO_TEST_CASE (DiskSameRadiusClustersProduceInfiniteSlopeTracklet)
496+ BOOST_AUTO_TEST_CASE (CylinderDisplacedChordPreservesBothLongitudinalSigns)
497+ {
498+ // A line parallel to x, displaced by y=1: its transverse length is exactly
499+ // one, while the difference of beam-axis radii is smaller than one.
500+ for (const float sign : {-1 .f , 1 .f }) {
501+ std::vector<DecodedCluster> clusters;
502+ for (int layer = 0 ; layer < 2 ; ++layer) {
503+ const float x = 3 .f + layer;
504+ const float z = sign * 0 .25f * (layer + 1 );
505+ auto cluster = cylinderCluster (x, z, layer);
506+ cluster.global .y = 1 .f ;
507+ cluster.cylinderFrame .u = 1 .f ;
508+ clusters.push_back (cluster);
509+ }
510+ const auto widenSearch = [](ReferenceTrackingParameters& p) {
511+ p.NSigmaCut = 100 .f ;
512+ p.PVres = 10 .f ; // Widen the independent azimuthal search gate too.
513+ };
514+ const auto serial = runFixture<ITSNLayers>(o2::detectors::DetID::ITS , SurfaceKind::Cylinder,
515+ SurfaceKind::Cylinder, clusters, 1 , widenSearch);
516+ const auto parallel = runFixture<ITSNLayers>(o2::detectors::DetID::ITS , SurfaceKind::Cylinder,
517+ SurfaceKind::Cylinder, clusters, 4 , widenSearch);
518+ const float expectedPhi = o2::gpu::CAMath::ATan2 (0 .f , -1 .f );
519+ checkExactTracklet (serial, sign * 0 .25f , expectedPhi);
520+ checkExactTracklet (parallel, sign * 0 .25f , expectedPhi);
521+ checkSame (serial, parallel);
522+ }
523+ }
524+
525+ BOOST_AUTO_TEST_CASE (DiskEqualRadiusDistinctHitsHaveFiniteSignedSlope)
526+ {
527+ const float fromZ = detail::mftLayerZ (0 );
528+ const float toZ = detail::mftLayerZ (1 );
529+ // Same radius, different positions, with a transverse chord of exactly one.
530+ const std::vector<DecodedCluster> clusters{
531+ diskCluster (1 .f , 0 .5f , fromZ, 0 ),
532+ diskCluster (1 .f , -0 .5f , toZ, 1 )};
533+ const auto widenSearch = [](ReferenceTrackingParameters& p) {
534+ p.NSigmaCut = 100 .f ;
535+ p.PVres = 10 .f ;
536+ };
537+ const auto serial = runFixture<MFTNLayers>(o2::detectors::DetID::MFT , SurfaceKind::Disk,
538+ SurfaceKind::Disk, clusters, 1 , widenSearch);
539+ const auto parallel = runFixture<MFTNLayers>(o2::detectors::DetID::MFT , SurfaceKind::Disk,
540+ SurfaceKind::Disk, clusters, 4 , widenSearch);
541+ const float expectedPhi = o2::gpu::CAMath::ATan2 (1 .f , 0 .f );
542+ checkExactTracklet (serial, toZ - fromZ, expectedPhi);
543+ checkExactTracklet (parallel, toZ - fromZ, expectedPhi);
544+ checkSame (serial, parallel);
545+ }
546+
547+ BOOST_AUTO_TEST_CASE (DiskZeroTransverseChordRejectsTracklet)
498548{
499549 const float fromZ = detail::mftLayerZ (0 );
500550 const float toZ = detail::mftLayerZ (1 );
@@ -506,10 +556,8 @@ BOOST_AUTO_TEST_CASE(DiskSameRadiusClustersProduceInfiniteSlopeTracklet)
506556 SurfaceKind::Disk, clusters, 1 , widenSearch);
507557 const auto parallel = runFixture<MFTNLayers>(o2::detectors::DetID::MFT , SurfaceKind::Disk,
508558 SurfaceKind::Disk, clusters, 4 , widenSearch);
509- const float expectedTanLambda = std::copysign (o2::constants::math::VeryBig, fromZ - toZ);
510- const float expectedPhi = o2::gpu::CAMath::ATan2 (0 .f , 0 .f );
511- checkExactTracklet (serial, expectedTanLambda, expectedPhi);
512- checkExactTracklet (parallel, expectedTanLambda, expectedPhi);
559+ BOOST_CHECK (serial.tracklets .empty ());
560+ BOOST_CHECK (parallel.tracklets .empty ());
513561 checkSame (serial, parallel);
514562}
515563
@@ -694,9 +742,8 @@ BOOST_AUTO_TEST_CASE(MftIdentityLayoutTrackletsSpanMultipleAdjacentEdgesInOrder)
694742 BOOST_CHECK_EQUAL (tracklet.secondClusterIndex , 0 );
695743 const auto & source = clusters[from].global ;
696744 const auto & target = clusters[to].global ;
697- const float sourceRadius = o2::gpu::CAMath::Hypot (source.x , source.y );
698- const float targetRadius = o2::gpu::CAMath::Hypot (target.x , target.y );
699- const float expectedTanLambda = (source.z - target.z ) / (sourceRadius - targetRadius);
745+ const float transverseChord = std::hypot (target.x - source.x , target.y - source.y );
746+ const float expectedTanLambda = (target.z - source.z ) / transverseChord;
700747 BOOST_CHECK_EQUAL (tracklet.tanLambda , expectedTanLambda);
701748 BOOST_CHECK_EQUAL_COLLECTIONS (snapshot.allLookups [id].begin (), snapshot.allLookups [id].end (), expectedLookup.begin (), expectedLookup.end ());
702749 sawEdge01 |= (from == 0 && to == 1 );
0 commit comments