From c9630721963323c1e76832c66524623564d21adc Mon Sep 17 00:00:00 2001 From: tobiaspk Date: Thu, 5 Mar 2026 17:19:36 -0500 Subject: [PATCH 1/3] Allow overriding scale_factor in visium hd --- src/spatialdata_io/readers/visium_hd.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/spatialdata_io/readers/visium_hd.py b/src/spatialdata_io/readers/visium_hd.py index d6513147..08b02e8b 100644 --- a/src/spatialdata_io/readers/visium_hd.py +++ b/src/spatialdata_io/readers/visium_hd.py @@ -161,6 +161,7 @@ def visium_hd( filename_prefix, dataset_id = _get_filename_prefix(path, dataset_id) def load_image(path: Path, suffix: str, scale_factors: list[int] | None = None) -> None: + scale_factors = image_models_kwargs.pop("scale_factors", scale_factors) _load_image( path=path, images=images, From 26967668ef49b7719a93b6bbf55f2eac05e6d5cc Mon Sep 17 00:00:00 2001 From: tobiaspk Date: Thu, 5 Mar 2026 17:30:26 -0500 Subject: [PATCH 2/3] Use MutableMappingt to allow `pop` --- src/spatialdata_io/readers/visium_hd.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/spatialdata_io/readers/visium_hd.py b/src/spatialdata_io/readers/visium_hd.py index 08b02e8b..09449bb4 100644 --- a/src/spatialdata_io/readers/visium_hd.py +++ b/src/spatialdata_io/readers/visium_hd.py @@ -34,7 +34,7 @@ from spatialdata_io.readers._utils._utils import _set_reader_metadata if TYPE_CHECKING: - from collections.abc import Mapping + from collections.abc import Mapping, MutableMapping from anndata import AnnData from multiscale_spatial_image import MultiscaleSpatialImage @@ -58,7 +58,7 @@ def visium_hd( load_all_images: bool = False, var_names_make_unique: bool = True, imread_kwargs: Mapping[str, Any] = MappingProxyType({}), - image_models_kwargs: Mapping[str, Any] = MappingProxyType({}), + image_models_kwargs: MutableMapping[str, Any] | None = None, anndata_kwargs: Mapping[str, Any] = MappingProxyType({}), ) -> SpatialData: """Read *10x Genomics* Visium HD formatted dataset. @@ -118,6 +118,8 @@ def visium_hd( shapes = {} images: dict[str, Any] = {} labels: dict[str, Any] = {} + if image_models_kwargs is None: + image_models_kwargs = {} # Deprecation warning for load_segmentations_only default value if load_segmentations_only is None: From 7b8d24c1a67b5d931880a98c1bd889b114b602a5 Mon Sep 17 00:00:00 2001 From: Luca Marconato Date: Thu, 30 Apr 2026 17:15:27 +0200 Subject: [PATCH 3/3] Fix mutation of image_models_kwargs and document scale_factors override Extract scale_factors from image_models_kwargs once via .get() into a local variable and build a filtered copy without the key, so the caller's mapping is never mutated. Reverts the signature back to Mapping[str, Any]. Adds docstring explaining the scale_factors special-case behaviour. Also fixes a missing colon on _infer_dataset_id introduced on the branch. Co-Authored-By: Claude Sonnet 4.6 --- src/spatialdata_io/readers/visium_hd.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/spatialdata_io/readers/visium_hd.py b/src/spatialdata_io/readers/visium_hd.py index 09449bb4..9e8ed9fe 100644 --- a/src/spatialdata_io/readers/visium_hd.py +++ b/src/spatialdata_io/readers/visium_hd.py @@ -34,7 +34,7 @@ from spatialdata_io.readers._utils._utils import _set_reader_metadata if TYPE_CHECKING: - from collections.abc import Mapping, MutableMapping + from collections.abc import Mapping from anndata import AnnData from multiscale_spatial_image import MultiscaleSpatialImage @@ -58,7 +58,7 @@ def visium_hd( load_all_images: bool = False, var_names_make_unique: bool = True, imread_kwargs: Mapping[str, Any] = MappingProxyType({}), - image_models_kwargs: MutableMapping[str, Any] | None = None, + image_models_kwargs: Mapping[str, Any] = MappingProxyType({}), anndata_kwargs: Mapping[str, Any] = MappingProxyType({}), ) -> SpatialData: """Read *10x Genomics* Visium HD formatted dataset. @@ -68,8 +68,8 @@ def visium_hd( path Path to directory containing the *10x Genomics* Visium HD output. dataset_id - Unique identifier of the dataset, used to name the elements of the `SpatialData` object. If `None`, it tries to - infer it from the file name of the feature slice file. + Unique identifier of the dataset, used to name the elements of the `SpatialData` object. If `None`, it is + inferred from the file name of the feature slice file. filtered_counts_file It sets the value of `counts_file` to ``{vx.FILTERED_COUNTS_FILE!r}`` (when `True`) or to ``{vx.RAW_COUNTS_FILE!r}`` (when `False`). @@ -105,6 +105,9 @@ def visium_hd( Keyword arguments for :func:`imageio.imread`. image_models_kwargs Keyword arguments for :class:`spatialdata.models.Image2DModel`. + The ``scale_factors`` key, when provided, overrides the scale factors used to downscale the full-resolution + image (default: ``[2, 2, 2, 2]``). The low-resolution images (i.e. "lowres", "hires", and "CytAssist") + ignore ``scale_factors`` and are always stored as single-scale images (:class:`xarray.DataArray`). anndata_kwargs Keyword arguments for :func:`anndata.io.read_h5ad`. @@ -118,8 +121,9 @@ def visium_hd( shapes = {} images: dict[str, Any] = {} labels: dict[str, Any] = {} - if image_models_kwargs is None: - image_models_kwargs = {} + DEFAULT_FULLRES_SCALEFACTORS = [2, 2, 2, 2] + _scale_factors_override: list[int] | None = image_models_kwargs.get("scale_factors", None) + _image_models_kwargs = {k: v for k, v in image_models_kwargs.items() if k != "scale_factors"} # Deprecation warning for load_segmentations_only default value if load_segmentations_only is None: @@ -163,14 +167,13 @@ def visium_hd( filename_prefix, dataset_id = _get_filename_prefix(path, dataset_id) def load_image(path: Path, suffix: str, scale_factors: list[int] | None = None) -> None: - scale_factors = image_models_kwargs.pop("scale_factors", scale_factors) _load_image( path=path, images=images, suffix=suffix, dataset_id=dataset_id, imread_kwargs=imread_kwargs, - image_models_kwargs=image_models_kwargs, + image_models_kwargs=_image_models_kwargs, scale_factors=scale_factors, ) @@ -430,7 +433,9 @@ def _get_bins(path_bins: Path) -> list[str]: load_image( path=Path(fullres_image_file), suffix="_full_image", - scale_factors=[2, 2, 2, 2], + scale_factors=_scale_factors_override + if _scale_factors_override is not None + else DEFAULT_FULLRES_SCALEFACTORS, ) else: warnings.warn(