@@ -570,12 +570,13 @@ def _flat_membrane_with_junctions(positions, shape=(12, 40, 40), z=6):
570570 labels [z , y , x ] = i
571571 return labels , membrane
572572
573- # These exercise compute_junction_distances directly; with no mesh supplied it meshes the given
574- # membrane and takes the surface geodesic, so they require the bioimage-cpp geodesic API.
573+ # These exercise compute_junction_distances directly. The metric is defined on the lumen surface,
574+ # so the mesh must be supplied explicitly (there is no membrane-band fallback); here the membrane's
575+ # own surface is meshed as the test fixture. They require the bioimage-cpp geodesic API.
575576 def test_geodesic_follows_bent_membrane (self ):
576577 # An L-shaped membrane: the geodesic around the bend is longer than the straight line
577578 # between the two seed voxels.
578- from synapse_net .cristae_analysis import compute_junction_distances
579+ from synapse_net .cristae_analysis import compute_junction_distances , _surface_mesh
579580 shape = (5 , 40 , 40 )
580581 membrane = np .zeros (shape , dtype = bool )
581582 z = 2
@@ -584,7 +585,10 @@ def test_geodesic_follows_bent_membrane(self):
584585 labels = np .zeros (shape , dtype = np .int32 )
585586 labels [z , 5 , 6 ] = 1 # near the far end of the horizontal arm
586587 labels [z , 33 , 34 ] = 2 # near the far end of the vertical arm
587- dist , _ = compute_junction_distances (labels , membrane , voxel_size = 1.0 )
588+ verts , faces = _surface_mesh (membrane , np .ones (3 ))
589+ dist , _ = compute_junction_distances (
590+ labels , membrane , voxel_size = 1.0 , mesh_vertices = verts , mesh_faces = faces
591+ )
588592 straight = np .sqrt ((33 - 5 ) ** 2 + (34 - 6 ) ** 2 )
589593 self .assertGreater (dist [0 , 1 ], straight * 1.2 )
590594
@@ -600,16 +604,21 @@ def test_fewer_than_two_junctions_is_nan(self):
600604 def test_clustered_index_lower_than_dispersed (self ):
601605 # Same membrane/area and junction count, but tightly grouped vs evenly spread:
602606 # the clustered arrangement must give a smaller Clark-Evans index.
603- from synapse_net .cristae_analysis import compute_junction_distances
607+ from synapse_net .cristae_analysis import compute_junction_distances , _surface_mesh
604608 area = 40.0 * 40.0
605609 clustered_pos = [(18 , 18 ), (18 , 20 ), (20 , 18 ), (20 , 20 )]
606610 dispersed_pos = [(8 , 8 ), (8 , 30 ), (30 , 8 ), (30 , 30 )]
607- _ , clustered = compute_junction_distances (
608- * self ._flat_membrane_with_junctions (clustered_pos ), voxel_size = 1.0 , surface_area_nm2 = area
609- )
610- _ , dispersed = compute_junction_distances (
611- * self ._flat_membrane_with_junctions (dispersed_pos ), voxel_size = 1.0 , surface_area_nm2 = area
612- )
611+
612+ def _cjd (positions ):
613+ labels , membrane = self ._flat_membrane_with_junctions (positions )
614+ verts , faces = _surface_mesh (membrane , np .ones (3 ))
615+ return compute_junction_distances (
616+ labels , membrane , voxel_size = 1.0 , surface_area_nm2 = area ,
617+ mesh_vertices = verts , mesh_faces = faces ,
618+ )
619+
620+ _ , clustered = _cjd (clustered_pos )
621+ _ , dispersed = _cjd (dispersed_pos )
613622 self .assertLess (clustered ["junction_clustering_index" ], dispersed ["junction_clustering_index" ])
614623
615624
@@ -936,18 +945,18 @@ def test_clipped_mito_open_mesh_finite(self):
936945 area_closed = _surface_area (mito_binary , np .ones (ndim ))
937946 self .assertLess (area_open , area_closed ) # the fabricated z-caps are no longer counted
938947
939- def test_primitive_mesh_on_flat_membrane (self ):
940- # With no mesh supplied the primitive meshes the given membrane surface — finite, positive,
941- # and of the right order (junctions ~17-20 apart). Absolute accuracy on a 1-voxel sheet is not
942- # asserted (that degenerate mesh is only the fallback; the pipeline meshes the thicker lumen).
948+ def test_no_mesh_supplied_is_nan (self ):
949+ # With no lumen mesh supplied the junction distances are NaN — there is no membrane-band
950+ # fallback mesh (the metric is defined on the eroded-mito lumen surface).
943951 from synapse_net .cristae_analysis import compute_junction_distances
944952 labels , membrane = TestJunctionDistances ._flat_membrane_with_junctions (
945953 [(20 , 8 ), (20 , 28 ), (8 , 20 ), (32 , 20 )]
946954 )
947955 _ , summary = compute_junction_distances (labels , membrane , 1.0 , surface_area_nm2 = 1000.0 )
948- mean_nn = summary ["mean_nn_junction_distance_nm" ]
949- self .assertTrue (np .isfinite (mean_nn ) and mean_nn > 0 )
950- self .assertLess (mean_nn , 100.0 ) # sane order of magnitude, not a runaway path
956+ self .assertEqual (summary ["junction_count" ], 4 )
957+ self .assertTrue (np .isnan (summary ["mean_nn_junction_distance_nm" ]))
958+ self .assertTrue (np .isnan (summary ["median_nn_junction_distance_nm" ]))
959+ self .assertTrue (np .isnan (summary ["junction_clustering_index" ]))
951960
952961
953962_EXPECTED_COLUMNS = [
0 commit comments