Skip to content

Commit 932703c

Browse files
committed
fix: fixes in tests + renaming for readability
1 parent ea28e55 commit 932703c

3 files changed

Lines changed: 70 additions & 31 deletions

File tree

src/spatialdata/_core/transformation_manager/__init__.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -375,8 +375,8 @@ def get_existing_direct_transformations(
375375
with suppress_direct_internal_attribute_access_warning():
376376
transforms = []
377377
assert target_cs in self.graph[source_cs], TransformationNotFoundError(source_cs.name, target_cs.name)
378-
for _edge_key, edge in self.graph[source_cs][target_cs]:
379-
transform: BaseTransformation = edge[TRANSFORM_KEY]
378+
for edge_data in self.graph[source_cs][target_cs].values():
379+
transform: BaseTransformation = edge_data[TRANSFORM_KEY]
380380
transforms.append(transform)
381381
return transforms
382382

@@ -415,7 +415,7 @@ def remove_specific_transformation(
415415
)
416416
self.graph.remove_edge(source_cs, target_cs, key=expected_edge_key)
417417

418-
def remove_all_transformations(
418+
def remove_all_transformations_between_coordinate_systems(
419419
self,
420420
source_cs: NgffCoordinateSystem,
421421
target_cs: NgffCoordinateSystem,
@@ -441,12 +441,13 @@ def remove_all_transformations(
441441
# also checks if source_cs and target_cs exist
442442
with suppress_direct_internal_attribute_access_warning():
443443
assert len(self.graph[source_cs][target_cs]), TransformationNotFoundError(source_cs.name, target_cs.name)
444-
for edge_key, _edge in self.graph[source_cs][target_cs]:
444+
for edge_key in list(self.graph[source_cs][target_cs].keys()):
445+
# need to covert keys() to list to freeze it, else it will change during the following removal
445446
self.graph.remove_edge(source_cs, target_cs, key=edge_key)
446447

447448
def _get_transformation_sequences_from_path_after_disambiguation(
448449
self,
449-
paths: Sequence[list[NgffCoordinateSystem]],
450+
paths: list[list[NgffCoordinateSystem]],
450451
expected_intermediate_transformations: list[BaseTransformation] | None,
451452
) -> list[list[BaseTransformation]]:
452453
"""
@@ -471,11 +472,12 @@ def _get_transformation_sequences_from_path_after_disambiguation(
471472
self._get_edge_key_from_transform(it) for it in expected_intermediate_transformations
472473
}
473474
all_sequences = []
474-
for path in paths:
475+
deduplicated_paths = list({repr(x): x for x in paths}.values())
476+
for path in deduplicated_paths:
475477
sequence = []
476478
for i in range(len(path) - 1):
477479
edge_data = self.graph[path[i]][path[i + 1]]
478-
if len(edge_data) >= 1:
480+
if len(edge_data) > 1:
479481
# when there are multiple edges between a pair of coordinate systems in the path
480482
intermediate_transformation_key_here = intermediate_transformation_edge_keys & set(edge_data.keys())
481483
if len(intermediate_transformation_key_here) == 0:
@@ -486,7 +488,9 @@ def _get_transformation_sequences_from_path_after_disambiguation(
486488
# choosing the first one arbitrarily
487489
sequence.append(edge_data[edge_key_to_use][TRANSFORM_KEY])
488490
else:
489-
sequence.append(edge_data[0][TRANSFORM_KEY])
491+
# Only one edge, no ambiguity
492+
edge_key = next(iter(edge_data.keys()))
493+
sequence.append(edge_data[edge_key][TRANSFORM_KEY])
490494
all_sequences.append(sequence)
491495
return all_sequences
492496

@@ -528,7 +532,7 @@ def get_all_shortest_transformation_sequences(
528532
"""
529533
with suppress_direct_internal_attribute_access_warning():
530534
try:
531-
paths = list(nx.shortest_simple_paths(self.graph, source=source_cs, target=target_cs))
535+
paths = list(nx.all_shortest_paths(self.graph, source=source_cs, target=target_cs))
532536

533537
except nx.NetworkXNoPath as nxe:
534538
raise TransformationPathNotFoundError(source_cs.name, target_cs.name) from nxe

tests/core/transformation_manager/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def four_point_graph() -> tuple[list[NgffCoordinateSystem], list[Scale | Transla
6262

6363

6464
@pytest.fixture
65-
def five_point_graph() -> tuple[list[NgffCoordinateSystem], list[Scale | Translation]]:
65+
def five_point_graph() -> tuple[list[NgffCoordinateSystem], list[Scale | Translation | Affine]]:
6666
"""Fixture providing a five-point graph with five coordinate systems and five transformations."""
6767

6868
coordinate_systems = [

tests/core/transformation_manager/test_transformation_manager.py

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,9 @@ def test_add_transformation(fully_connected_two_point_graph):
192192
tm.add_transformation(cs1, cs2, transform)
193193

194194
assert tm.graph.has_edge(cs1, cs2)
195-
assert tm.graph[cs1][cs2][0][TRANSFORM_KEY] == transform
195+
# Get the first edge key and check the transformation
196+
edge_key = tm._get_edge_key_from_transform(transform)
197+
assert tm.graph[cs1][cs2][edge_key][TRANSFORM_KEY] == transform
196198

197199

198200
def test_add_transformation_nonexistent_cs(fully_connected_two_point_graph):
@@ -224,7 +226,7 @@ def test_get_existing_transformation(fully_connected_two_point_graph):
224226
tm.add_transformation(cs1, cs2, transform)
225227

226228
retrieved = tm.get_existing_direct_transformations(cs1, cs2)
227-
assert retrieved == transform
229+
assert retrieved == [transform]
228230

229231

230232
def test_get_existing_transformation_nonexistent(fully_connected_two_point_graph):
@@ -241,8 +243,8 @@ def test_get_existing_transformation_nonexistent(fully_connected_two_point_graph
241243
tm.get_existing_direct_transformations(cs1, cs2)
242244

243245

244-
def test_remove_transformation(fully_connected_two_point_graph):
245-
"""Test removing a transformation."""
246+
def test_remove_all_transformations_between_coordinate_systems(fully_connected_two_point_graph):
247+
"""Test removing all transformations between coordinate systems."""
246248
with suppress_direct_internal_attribute_access_warning():
247249
tm = TransformationManager()
248250
[cs1, cs2], [transform] = fully_connected_two_point_graph
@@ -251,12 +253,12 @@ def test_remove_transformation(fully_connected_two_point_graph):
251253

252254
tm.add_transformation(cs1, cs2, transform)
253255

254-
tm.remove_all_transformations(cs1, cs2)
256+
tm.remove_all_transformations_between_coordinate_systems(cs1, cs2)
255257
assert not tm.graph.has_edge(cs1, cs2)
256258

257259

258-
def test_remove_transformation_nonexistent(fully_connected_two_point_graph):
259-
"""Test that removing a non-existent transformation raises TransformationNotFoundError."""
260+
def test_remove_all_transformation_nonexistent(fully_connected_two_point_graph):
261+
"""Test that removing non-existent transformations between coordinate systems raises TransformationNotFoundError."""
260262
with suppress_direct_internal_attribute_access_warning():
261263
tm = TransformationManager()
262264
[cs1, cs2], _ = fully_connected_two_point_graph
@@ -265,7 +267,41 @@ def test_remove_transformation_nonexistent(fully_connected_two_point_graph):
265267
with pytest.raises(
266268
TransformationNotFoundError, match=f"Transformation from '{cs1.name}' to '{cs2.name}' not found"
267269
):
268-
tm.remove_all_transformations(cs1, cs2)
270+
tm.remove_all_transformations_between_coordinate_systems(cs1, cs2)
271+
272+
273+
def test_remove_specific_transformation_between_coordinate_systems(five_point_graph):
274+
"""Test removing specific transformation between coordinate systems."""
275+
276+
with suppress_direct_internal_attribute_access_warning():
277+
tm = TransformationManager()
278+
[_cs1, _cs2, cs3, _cs4, cs5], [_transform1, _transform2, _transform3, transform4, transform5] = five_point_graph
279+
tm.add_coordinate_system(cs3)
280+
tm.add_coordinate_system(cs5)
281+
282+
tm.add_transformation(cs3, cs5, transform4)
283+
tm.add_transformation(cs3, cs5, transform5)
284+
285+
tm.remove_specific_transformation(cs3, cs5, transform4)
286+
assert not tm.graph.has_edge(cs3, cs5, key=tm._get_edge_key_from_transform(transform4))
287+
288+
289+
def test_remove_specific_transformation_between_coordinate_systems_non_existent(five_point_graph):
290+
"""
291+
Test that removing non-existent specific transformation between coordinate systems raises
292+
TransformationNotFoundError.
293+
"""
294+
295+
with suppress_direct_internal_attribute_access_warning():
296+
tm = TransformationManager()
297+
[_cs1, _cs2, cs3, _cs4, cs5], [_transform1, _transform2, _transform3, transform4, transform5] = five_point_graph
298+
tm.add_coordinate_system(cs3)
299+
tm.add_coordinate_system(cs5)
300+
301+
with pytest.raises(
302+
TransformationNotFoundError, match=f"Transformation from '{cs3.name}' to '{cs5.name}' not found"
303+
):
304+
tm.remove_specific_transformation(cs3, cs5, transform4)
269305

270306

271307
def test_get_all_shortest_transformation_sequences_direct(four_point_graph):
@@ -354,17 +390,16 @@ def test_get_all_shortest_transformation_sequences_multiple_paths_multiple_edges
354390
tm.add_transformation(cs2, cs3, transform2)
355391
tm.add_transformation(cs1, cs4, transform2)
356392
tm.add_transformation(cs4, cs3, transform1)
357-
tm.add_transformation(cs1, cs3, transform3)
358-
tm.add_transformation(cs4, cs5, transform4)
359-
tm.add_transformation(cs4, cs5, transform5)
393+
# tm.add_transformation(cs1, cs3, transform3)
394+
tm.add_transformation(cs3, cs5, transform4)
395+
tm.add_transformation(cs3, cs5, transform5)
360396

361397
sequences = tm.get_all_shortest_transformation_sequences(
362398
cs1, cs5, expected_intermediate_transformations=[transform4]
363399
)
364-
assert len(sequences) == 3
400+
assert len(sequences) == 2
365401
assert [transform1, transform2, transform4] in sequences
366402
assert [transform2, transform1, transform4] in sequences
367-
assert [transform3, transform4] in sequences
368403

369404

370405
def test_get_all_shortest_transformation_sequences_multiple_paths_multiple_edges_failure(five_point_graph):
@@ -382,11 +417,11 @@ def test_get_all_shortest_transformation_sequences_multiple_paths_multiple_edges
382417
tm.add_transformation(cs1, cs4, transform2)
383418
tm.add_transformation(cs4, cs3, transform1)
384419
tm.add_transformation(cs1, cs3, transform3)
385-
tm.add_transformation(cs4, cs5, transform4)
386-
tm.add_transformation(cs4, cs5, transform5)
420+
tm.add_transformation(cs3, cs5, transform4)
421+
tm.add_transformation(cs3, cs5, transform5)
387422

388423
with pytest.raises(TransformationPathAmbiguousError, match="Transformation Path ambiguous"):
389-
tm.get_all_shortest_transformation_sequences(cs1, cs5, expected_intermediate_transformations=[transform4])
424+
tm.get_all_shortest_transformation_sequences(cs1, cs5)
390425

391426

392427
def test_get_all_transformation_sequences(four_point_graph):
@@ -446,8 +481,8 @@ def test_get_all_transformation_sequences_multiple_paths_multiple_edges_success(
446481
tm.add_transformation(cs1, cs4, transform2)
447482
tm.add_transformation(cs4, cs3, transform1)
448483
tm.add_transformation(cs1, cs3, transform3)
449-
tm.add_transformation(cs4, cs5, transform4)
450-
tm.add_transformation(cs4, cs5, transform5)
484+
tm.add_transformation(cs3, cs5, transform4)
485+
tm.add_transformation(cs3, cs5, transform5)
451486

452487
sequences = tm.get_all_transformation_sequences(cs1, cs5, expected_intermediate_transformations=[transform4])
453488
assert len(sequences) == 3
@@ -471,11 +506,11 @@ def test_get_all_transformation_sequences_multiple_paths_multiple_edges_failure(
471506
tm.add_transformation(cs1, cs4, transform2)
472507
tm.add_transformation(cs4, cs3, transform1)
473508
tm.add_transformation(cs1, cs3, transform3)
474-
tm.add_transformation(cs4, cs5, transform4)
475-
tm.add_transformation(cs4, cs5, transform5)
509+
tm.add_transformation(cs3, cs5, transform4)
510+
tm.add_transformation(cs3, cs5, transform5)
476511

477512
with pytest.raises(TransformationPathAmbiguousError, match="Transformation Path ambiguous"):
478-
tm.get_all_transformation_sequences(cs1, cs5, expected_intermediate_transformations=[transform4])
513+
tm.get_all_transformation_sequences(cs1, cs5)
479514

480515

481516
def test_get_all_transformation_sequences_no_path(four_point_graph):

0 commit comments

Comments
 (0)