@@ -811,7 +811,7 @@ BOOST_AUTO_TEST_CASE(CylinderCellCombinationUsesTrackletMinPtScattering)
811811 BOOST_CHECK_EQUAL (acceptedCells (1 .f ), 0u );
812812}
813813
814- BOOST_AUTO_TEST_CASE (ForwardCellProjectsScatteringIntoAzimuth )
814+ BOOST_AUTO_TEST_CASE (ForwardCellAcceptsBendingWithinScatteringTolerance )
815815{
816816 Rig<MFTNLayers> rig{o2::detectors::DetID::MFT , SurfaceKind::Disk};
817817 rig.params [0 ].TrackletMinPt = 0 .3f ;
@@ -824,11 +824,11 @@ BOOST_AUTO_TEST_CASE(ForwardCellProjectsScatteringIntoAzimuth)
824824 const std::array<GlobalMeasurement, 3 > clusters{
825825 makeGlobalCluster (1 .f , 0 .f , -0 .4f ),
826826 makeGlobalCluster (1 .01f , 0 .f , -0 .6f ),
827- makeGlobalCluster (1 .01995f , 0 .000998f , -0 .9f )};
827+ makeGlobalCluster (1 .01995f , 0 .000998f , -0 .8f )};
828828 loadCandidateClusters (rig, clusters,
829829 {makeDiskHit (-0 .4f , 1 .f , 0 .f ),
830830 makeDiskHit (-0 .6f , 1 .01f , 0 .f ),
831- makeDiskHit (-0 .9f , 1 .01995f , 0 .000998f )});
831+ makeDiskHit (-0 .8f , 1 .01995f , 0 .000998f )});
832832
833833 auto view = prepare (rig);
834834 const auto topology = topologyView (rig);
@@ -840,6 +840,79 @@ BOOST_AUTO_TEST_CASE(ForwardCellProjectsScatteringIntoAzimuth)
840840 BOOST_CHECK_EQUAL (rig.tf ->getCells ()[cellIndex].size (), 1u );
841841}
842842
843+ BOOST_AUTO_TEST_CASE (ForwardCellAzimuthalToleranceDoesNotGrowWithTanLambda)
844+ {
845+ auto acceptedCells = [](float deltaPhi, float deltaZ) {
846+ Rig<MFTNLayers> rig{o2::detectors::DetID::MFT , SurfaceKind::Disk};
847+ rig.params [0 ].TrackletMinPt = 0 .3f ;
848+ rig.params [0 ].MaxChi2ClusterAttachment = 1 .e6f ;
849+ rig.params [0 ].LayerxX0 [1 ] = 0 .017f ;
850+ rig.establishLayout ();
851+
852+ // Equal transverse lengths and longitudinal steps keep the dip-angle
853+ // difference zero. Only the bend and the common inclination vary.
854+ const float outerX = 1 .01f + 0 .01f * std::cos (deltaPhi);
855+ const float outerY = 0 .01f * std::sin (deltaPhi);
856+ const std::array<GlobalMeasurement, 3 > clusters{
857+ makeGlobalCluster (1 .f , 0 .f , -0 .4f ),
858+ makeGlobalCluster (1 .01f , 0 .f , -0 .4f - deltaZ),
859+ makeGlobalCluster (outerX, outerY, -0 .4f - 2 .f * deltaZ)};
860+ loadCandidateClusters (rig, clusters,
861+ {makeDiskHit (clusters[0 ].z , clusters[0 ].x , clusters[0 ].y ),
862+ makeDiskHit (clusters[1 ].z , clusters[1 ].x , clusters[1 ].y ),
863+ makeDiskHit (clusters[2 ].z , clusters[2 ].x , clusters[2 ].y )});
864+
865+ auto view = prepare (rig);
866+ const int cellIndex = findCellIndex (topologyView (rig), 0 , 1 , 2 );
867+ BOOST_REQUIRE_GE (cellIndex, 0 );
868+ injectCandidateTracklets (rig, cellIndex, clusters);
869+ TrackerTestAccess::computeCells (rig.traits , view);
870+ return rig.tf ->getCells ()[cellIndex].size ();
871+ };
872+
873+ for (const float deltaZ : {0 .2f , 0 .8f }) {
874+ BOOST_CHECK_EQUAL (acceptedCells (0 .02f , deltaZ), 1u );
875+ BOOST_CHECK_EQUAL (acceptedCells (0 .2f , deltaZ), 0u );
876+ }
877+ }
878+
879+ BOOST_AUTO_TEST_CASE (ForwardCellDipToleranceScalesWithInclination)
880+ {
881+ auto acceptedCells = [](float meanTanLambda, float deltaLambda) {
882+ Rig<MFTNLayers> rig{o2::detectors::DetID::MFT , SurfaceKind::Disk};
883+ rig.params [0 ].TrackletMinPt = 0 .3f ;
884+ rig.params [0 ].LayerxX0 [1 ] = 0 .017f ;
885+ rig.establishLayout ();
886+
887+ // No transverse bend: isolate the dip-angle difference around a chosen
888+ // common inclination, keeping the transverse segment lengths fixed.
889+ const float meanLambda = std::atan (meanTanLambda);
890+ const float middleZ = -0 .4f + 0 .01f * std::tan (meanLambda - 0 .5f * deltaLambda);
891+ const float outerZ = middleZ + 0 .01f * std::tan (meanLambda + 0 .5f * deltaLambda);
892+ const std::array<GlobalMeasurement, 3 > clusters{
893+ makeGlobalCluster (1 .f , 0 .f , -0 .4f ),
894+ makeGlobalCluster (1 .01f , 0 .f , middleZ),
895+ makeGlobalCluster (1 .02f , 0 .f , outerZ)};
896+ loadCandidateClusters (rig, clusters,
897+ {makeDiskHit (clusters[0 ].z , clusters[0 ].x , clusters[0 ].y ),
898+ makeDiskHit (clusters[1 ].z , clusters[1 ].x , clusters[1 ].y ),
899+ makeDiskHit (clusters[2 ].z , clusters[2 ].x , clusters[2 ].y )});
900+
901+ auto view = prepare (rig);
902+ const int cellIndex = findCellIndex (topologyView (rig), 0 , 1 , 2 );
903+ BOOST_REQUIRE_GE (cellIndex, 0 );
904+ injectCandidateTracklets (rig, cellIndex, clusters);
905+ TrackerTestAccess::computeCells (rig.traits , view);
906+ return rig.tf ->getCells ()[cellIndex].size ();
907+ };
908+
909+ for (const float sign : {-1 .f , 1 .f }) {
910+ BOOST_CHECK_EQUAL (acceptedCells (sign * 20 .f , 0 .001f ), 1u );
911+ BOOST_CHECK_EQUAL (acceptedCells (sign * 5 .f , 0 .01f ), 1u );
912+ BOOST_CHECK_EQUAL (acceptedCells (sign * 20 .f , 0 .01f ), 0u );
913+ }
914+ }
915+
843916// --- Disk: real orchestration matches the generic cell-seed oracle -------
844917
845918BOOST_AUTO_TEST_CASE (DiskComputeLayerCellsMatchesBuildCellSeedOracle)
0 commit comments