scverse / scverse/spatialdata

sd.concatenate throws ValidationError on queried sdatas

Open
#924 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
394
Forks
95
Avg merge
4d 3h
Merged PRs (30d)
7

Description

Bug Description

Concatenating two SpatialData objects extracted from bounding boxes fails with a ValidationError.

To Reproduce
import spatialdata as sd

sdata = sd.datasets.blobs()
sdata1 = sdata.query.bounding_box(('x', 'y'), min_coordinate=2*[0], max_coordinate=2*[100], target_coordinate_system='global')
sdata2 = sdata.query.bounding_box(('x', 'y'), min_coordinate=2*[100], max_coordinate=2*[200], target_coordinate_system='global')
sdata_concat = sd.concatenate({'s1': sdata1, 's2': sdata2})
Error Message
---------------------------------------------------------------------------
ValidationError                           Traceback (most recent call last)
Cell In[1], line 6
      4 sdata1 = sdata.query.bounding_box(('x', 'y'), min_coordinate=2*[0], max_coordinate=2*[100], target_coordinate_system='global')
      5 sdata2 = sdata.query.bounding_box(('x', 'y'), min_coordinate=2*[100], max_coordinate=2*[200], target_coordinate_system='global')
----> 6 sdata_concat = sd.concatenate({'s1': sdata1, 's2': sdata2})

File ~/miniforge3/envs/workshop_2025_spatial/lib/python3.12/site-packages/spatialdata/_core/concatenate.py:139, in concatenate(sdatas, region_key, instance_key, concatenate_tables, obs_names_make_unique, modify_tables_inplace, attrs_merge, **kwargs)
    136     raise TypeError("`sdatas` must be a `Iterable`")
    138 if isinstance(sdatas, dict):
--> 139     sdatas = _fix_ensure_unique_element_names(
    140         sdatas,
    141         rename_tables=not concatenate_tables,
    142         rename_obs_names=obs_names_make_unique and concatenate_tables,
    143         modify_tables_inplace=modify_tables_inplace,
    144     )
    146 ERROR_STR = (
    147     " must have unique names across the SpatialData objects to concatenate. Please pass a `dict[str, SpatialData]`"
    148     " to `concatenate()` to address this (see docstring)."
    149 )
    151 merged_images = {**{k: v for sdata in sdatas for k, v in sdata.images.items()}}

File ~/miniforge3/envs/workshop_2025_spatial/lib/python3.12/site-packages/spatialdata/_core/concatenate.py:251, in _fix_ensure_unique_element_names(sdatas, rename_tables, rename_obs_names, modify_tables_inplace)
    249 sdatas_fixed = []
    250 for elements, tables in zip(elements_by_sdata, tables_by_sdata, strict=True):
--> 251     sdata = SpatialData.init_from_elements(elements, tables=tables)
    252     sdatas_fixed.append(sdata)
    253 return sdatas_fixed

File ~/miniforge3/envs/workshop_2025_spatial/lib/python3.12/site-packages/spatialdata/_core/spatialdata.py:2299, in SpatialData.init_from_elements(cls, elements, tables, attrs)
   2297         for name, table in tables.items():
   2298             elements_dict["tables"][name] = table
-> 2299 return cls(**elements_dict, attrs=attrs)

File ~/miniforge3/envs/workshop_2025_spatial/lib/python3.12/site-packages/spatialdata/_utils.py:270, in _deprecation_alias.<locals>.deprecation_decorator.<locals>.wrapper(*args, **kwargs)
    268     raise ValueError("version for deprecation must be specified")
    269 rename_kwargs(f.__name__, kwargs, alias_copy, class_name, library, version)
--> 270 return f(*args, **kwargs)

File ~/miniforge3/envs/workshop_2025_spatial/lib/python3.12/site-packages/spatialdata/_core/spatialdata.py:156, in SpatialData.__init__(self, images, labels, points, shapes, tables, attrs)
    151     duplicates = {x for x in element_names if element_names.count(x) > 1}
    152     raise KeyError(
    153         f"Element names must be unique. The following element names are used multiple times: {duplicates}"
    154     )
--> 156 with raise_validation_errors(
    157     title="Cannot construct SpatialData object, input contains invalid elements.\n"
    158     "For renaming, please see the discussion here https://github.com/scverse/spatialdata/discussions/707 .",
    159     exc_type=(ValueError, KeyError),
    160 ) as collect_error:
    162     if images is not None:
    163         for k, v in images.items():

File ~/miniforge3/envs/workshop_2025_spatial/lib/python3.12/site-packages/spatialdata/_core/validation.py:382, in raise_validation_errors.__exit__(self, exc_type, exc_val, exc_tb)
    380 # Exceptions were collected that we want to raise as a combined validation error.
    381 if self._collector.errors:
--> 382     raise ValidationError(title=self._message, errors=self._collector.errors)
    383 return True

ValidationError: Cannot construct SpatialData object, input contains invalid elements.
For renaming, please see the discussion here https://github.com/scverse/spatialdata/discussions/707 .
  tables/table-s1: Regions in the AnnData object and `region` do not match.
Expected Behavior

The concatenate function should successfully merge the two bounding box subsets of sdata.

System Info
  • OS: macOS 14.7.5
  • Python version: 3.12.9
  • SpatialData version: 0.3.0
Package Versions
Package Version
spatialdata 0.3.0
numpy 2.1.3
pandas 2.2.3
xarray 2025.3.1
dask 2024.11.2
zarr 2.18.5
pyproj 3.7.1
shapely 2.1.0
scikit-image 0.25.2
anndata 0.11.4
ome-zarr 0.10.3
multiscale_spatial_image 2.0.2

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in spatialdata/_core/concatenate.py at concatenate() and _fix_ensure_unique_element_names(), then inspect SpatialData.init_from_elements() in spatialdata/_core/spatialdata.py. Reproduce the issue with the bounding-box snippet and trace why the queried tables' regions do not match. Done means concatenating the two queried SpatialData objects completes without a ValidationError.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
data
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.