-
Notifications
You must be signed in to change notification settings - Fork 71
Added parameter to sd.concatenate
to control whether to merge coordinate systems with the same name
#919
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Added parameter to sd.concatenate
to control whether to merge coordinate systems with the same name
#919
Changes from 5 commits
a78d460
19ef82a
0cc33d9
604511e
d542564
2cffb17
1a800c7
3f32484
c99e304
5c5fb38
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,12 @@ | |
|
||
from spatialdata._core._utils import _find_common_table_keys | ||
from spatialdata._core.spatialdata import SpatialData | ||
from spatialdata.models import SpatialElement, TableModel, get_table_keys | ||
from spatialdata.models import TableModel, get_table_keys | ||
from spatialdata.transformations import ( | ||
get_transformation, | ||
remove_transformation, | ||
set_transformation, | ||
) | ||
|
||
__all__ = [ | ||
"concatenate", | ||
|
@@ -81,7 +86,8 @@ def concatenate( | |
concatenate_tables: bool = False, | ||
obs_names_make_unique: bool = True, | ||
modify_tables_inplace: bool = False, | ||
attrs_merge: StrategiesLiteral | Callable[[list[dict[Any, Any]]], dict[Any, Any]] | None = None, | ||
merge_coordinate_systems_on_name: bool = False, | ||
attrs_merge: (StrategiesLiteral | Callable[[list[dict[Any, Any]]], dict[Any, Any]] | None) = None, | ||
**kwargs: Any, | ||
) -> SpatialData: | ||
""" | ||
|
@@ -141,6 +147,7 @@ def concatenate( | |
rename_tables=not concatenate_tables, | ||
rename_obs_names=obs_names_make_unique and concatenate_tables, | ||
modify_tables_inplace=modify_tables_inplace, | ||
merge_coordinate_systems_on_name=merge_coordinate_systems_on_name, | ||
) | ||
|
||
ERROR_STR = ( | ||
|
@@ -222,12 +229,14 @@ def _fix_ensure_unique_element_names( | |
rename_tables: bool, | ||
rename_obs_names: bool, | ||
modify_tables_inplace: bool, | ||
merge_coordinate_systems_on_name: bool, | ||
) -> list[SpatialData]: | ||
elements_by_sdata: list[dict[str, SpatialElement]] = [] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this refactoring is fine |
||
tables_by_sdata: list[dict[str, AnnData]] = [] | ||
sdatas_fixed = [] | ||
for suffix, sdata in sdatas.items(): | ||
# Create new elements dictionary with suffixed names | ||
elements = {f"{name}-{suffix}": el for _, name, el in sdata.gen_spatial_elements()} | ||
elements_by_sdata.append(elements) | ||
|
||
# Handle tables with suffix | ||
tables = {} | ||
for name, table in sdata.tables.items(): | ||
if not modify_tables_inplace: | ||
|
@@ -251,9 +260,27 @@ def _fix_ensure_unique_element_names( | |
# fix the table name | ||
new_name = f"{name}-{suffix}" if rename_tables else name | ||
tables[new_name] = table | ||
tables_by_sdata.append(tables) | ||
sdatas_fixed = [] | ||
for elements, tables in zip(elements_by_sdata, tables_by_sdata, strict=True): | ||
sdata = SpatialData.init_from_elements(elements, tables=tables) | ||
sdatas_fixed.append(sdata) | ||
|
||
# Create new SpatialData object with suffixed elements and tables | ||
sdata_fixed = SpatialData.init_from_elements(elements, tables=tables) | ||
|
||
# Handle coordinate systems and transformations | ||
for element_name, element in elements.items(): | ||
# Get the original element from the input sdata | ||
original_name = element_name.replace(f"-{suffix}", "") | ||
|
||
original_element = sdata.get(original_name) | ||
|
||
# Get transformations from original element | ||
transformations = get_transformation(original_element, get_all=True) | ||
assert isinstance(transformations, dict) | ||
|
||
timtreis marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
# Remove any existing transformations from the new element | ||
remove_transformation(element, remove_all=True) | ||
|
||
|
||
# Set new transformations with suffixed coordinate system names | ||
for cs, t in transformations.items(): | ||
new_cs = cs if merge_coordinate_systems_on_name else f"{cs}-{suffix}" | ||
set_transformation(element, t, to_coordinate_system=new_cs) | ||
|
||
sdatas_fixed.append(sdata_fixed) | ||
return sdatas_fixed |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import pytest | ||
|
||
|
||
import spatialdata as sd | ||
from spatialdata.datasets import blobs | ||
|
||
|
||
@pytest.mark.parametrize("merge_coordinate_systems_on_name", [True, False]) | ||
def test_concatenate_merge_coordinate_systems_on_name(merge_coordinate_systems_on_name): | ||
blob1 = blobs() | ||
blob2 = blobs() | ||
|
||
sdata_keys = ["blob1", "blob2"] | ||
sdata = sd.concatenate( | ||
dict(zip(sdata_keys, [blob1, blob2], strict=True)), | ||
merge_coordinate_systems_on_name=merge_coordinate_systems_on_name, | ||
) | ||
|
||
expected_images = ["blobs_image", "blobs_multiscale_image"] | ||
expected_labels = ["blobs_labels", "blobs_multiscale_labels"] | ||
expected_points = ["blobs_points"] | ||
expected_shapes = ["blobs_circles", "blobs_polygons", "blobs_multipolygons"] | ||
|
||
expected_suffixed_images = [f"{name}-{key}" for key in sdata_keys for name in expected_images] | ||
expected_suffixed_labels = [f"{name}-{key}" for key in sdata_keys for name in expected_labels] | ||
expected_suffixed_points = [f"{name}-{key}" for key in sdata_keys for name in expected_points] | ||
expected_suffixed_shapes = [f"{name}-{key}" for key in sdata_keys for name in expected_shapes] | ||
|
||
assert set(sdata.images.keys()) == set(expected_suffixed_images) | ||
assert set(sdata.labels.keys()) == set(expected_suffixed_labels) | ||
assert set(sdata.points.keys()) == set(expected_suffixed_points) | ||
assert set(sdata.shapes.keys()) == set(expected_suffixed_shapes) | ||
|
||
if merge_coordinate_systems_on_name: | ||
assert sdata.coordinate_systems == ["global"] | ||
else: | ||
assert sdata.coordinate_systems == ["global-blob1", "global-blob2"] | ||
timtreis marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.