Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ test = [
"pytest>=7",
"pytest-xdist>=3",
"pytest-mock>=3.5.0",
# Just for VS Code
"pytest-cov>=4",
"coverage[toml]>=7",
"pytest-timeout>=2.1.0",
Expand Down
17 changes: 16 additions & 1 deletion src/squidpy/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
from multiprocessing import Manager, cpu_count
from queue import Queue
from threading import Thread
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, Literal

import joblib as jl
import numba
import numpy as np
import spatialdata as sd
import xarray as xr
from spatialdata.models import Image2DModel, Labels2DModel

__all__ = ["singledispatchmethod", "Signal", "SigQueue", "NDArray", "NDArrayA"]
Expand Down Expand Up @@ -373,3 +374,17 @@ def _yx_from_shape(shape: tuple[int, ...]) -> tuple[int, int]:
return shape[1], shape[2]

raise ValueError(f"Unsupported shape {shape}. Expected (y, x) or (c, y, x).")


def _ensure_dim_order(img_da: xr.DataArray, order: Literal["cyx", "yxc"] = "yxc") -> xr.DataArray:
"""
Ensure dims are in the requested order and that a 'c' dim exists.
Only supports images with dims subset of {'y','x','c'}.
"""
dims = list(img_da.dims)
if "y" not in dims or "x" not in dims:
raise ValueError(f'Expected dims to include "y" and "x". Found dims={dims}')
if "c" not in dims:
img_da = img_da.expand_dims({"c": [0]})
# After possible expand, just transpose to target
return img_da.transpose(*tuple(order))
6 changes: 5 additions & 1 deletion src/squidpy/datasets/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,11 @@ def _extension(self) -> str:
def _get_zipped_dataset(folderpath: Path, dataset_name: str, figshare_id: str) -> sd.SpatialData:
"""Returns a specific dataset as SpatialData object. If the file is not present on disk, it will be downloaded and extracted."""

if not folderpath.is_dir():
# Create directory if it doesn't exist
if not folderpath.exists():
logg.info(f"Creating directory `{folderpath}`")
folderpath.mkdir(parents=True, exist_ok=True)
elif not folderpath.is_dir():
raise ValueError(f"Expected a directory path for `folderpath`, found: {folderpath}")

download_zip = folderpath / f"{dataset_name}.zip"
Expand Down
5 changes: 2 additions & 3 deletions src/squidpy/experimental/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from __future__ import annotations

from . import im
from .im._detect_tissue import detect_tissue
from . import im, pl

__all__ = ["detect_tissue", "im"]
__all__ = ["im", "pl"]
10 changes: 9 additions & 1 deletion src/squidpy/experimental/im/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,13 @@
FelzenszwalbParams,
detect_tissue,
)
from ._qc_sharpness import qc_sharpness
from ._sharpness_metrics import SharpnessMetric

__all__ = ["detect_tissue", "BackgroundDetectionParams", "FelzenszwalbParams"]
__all__ = [
"qc_sharpness",
"detect_tissue",
"SharpnessMetric",
"BackgroundDetectionParams",
"FelzenszwalbParams",
]
8 changes: 5 additions & 3 deletions src/squidpy/experimental/im/_detect_tissue.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
from spatialdata.models import Labels2DModel
from spatialdata.transformations import get_transformation

from squidpy._utils import _get_scale_factors, _yx_from_shape
from squidpy._utils import _ensure_dim_order, _get_scale_factors, _yx_from_shape

from ._utils import _flatten_channels, _get_image_data
from ._utils import _flatten_channels, _get_element_data


class DETECT_TISSUE_METHOD(enum.Enum):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed this Enum. I think the Enum classes themselves are supposed to be in UpperCamelCase.

https://docs.python.org/3/howto/enum.html

Because Enums are used to represent constants, and to help avoid issues with name clashes between mixin-class methods/attributes and enum names, we strongly recommend using UPPER_CASE names for members, and will be using that style in our examples.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class DETECT_TISSUE_METHOD(enum.Enum):
class DetectTissueMethod(enum.Enum):

Expand Down Expand Up @@ -170,7 +170,9 @@ def detect_tissue(
manual_scale = scale.lower() != "auto"

# Load smallest available or explicit scale
img_src = _get_image_data(sdata, image_key, scale=scale if manual_scale else "auto")
img_node = sdata.images[image_key]
img_da = _get_element_data(img_node, scale if manual_scale else "auto", "image", image_key)
img_src = _ensure_dim_order(img_da, "yxc")
src_h, src_w = _yx_from_shape(img_src.shape)
n_src_px = src_h * src_w

Expand Down
Loading