Skip to content

Expected width to be in interval error im.calculate_image_features #989

@mjakobs

Description

@mjakobs

Description

Firstly, thank you for this wonderful package.

The error I'm encountering looks like the same as the one reported in #878 which was closed without an answer.

When running sq.im.calculate_image_features on certain Visium slides it fails with some version of the following error:
ValueError: Expected `width` to be in interval `[0, 1985]`, found `2026`.

This currently happens for 50% of the samples that I'm working with, for the other 50% the function works as expected.

Minimal example

adata = sc.read_visium('/path/to/Aligned/spaceranger/' + 'sample' + '/outs/', 
                        count_file='filtered_feature_bc_matrix.h5', 
                        source_image_path='/path/to/Aligned/spaceranger/' + 'sample' + '/outs/spatial/tissue_hires_image.png')

scale = adata.uns["spatial"]['sample']["scalefactors"]["tissue_hires_scalef"]
img = sq.im.ImageContainer(adata.uns["spatial"]['sample']["images"]["hires"], scale = scale) 

sq.im.calculate_image_features(
        adata,
        img,
        layer= "image",
        features="summary",
        key_added="features_summary_mean",
        mask_circle = True
    )

The result of img.shape is (2000, 1985)

Traceback

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[8], line 1
----> 1 sq.im.calculate_image_features(
      2         adata,
      3         img,
      4         layer= "image",
      5         features="summary",
      6         key_added="features_summary_mean",
      7         mask_circle = True
      8     )

File /path/to/squidpy_env/lib/python3.9/site-packages/squidpy/im/_feature.py:90, in calculate_image_features(adata, img, layer, library_id, features, features_kwargs, key_added, copy, n_jobs, backend, show_progress_bar, **kwargs)
     87 n_jobs = _get_n_cores(n_jobs)
     88 start = logg.info(f"Calculating features `{list(features)}` using `{n_jobs}` core(s)")
---> 90 res = parallelize(
     91     _calculate_image_features_helper,
     92     collection=adata.obs_names,
     93     extractor=pd.concat,
     94     n_jobs=n_jobs,
     95     backend=backend,
     96     show_progress_bar=show_progress_bar,
     97 )(adata, img, layer=layer, library_id=library_id, features=features, features_kwargs=features_kwargs, **kwargs)
     99 if copy:
    100     logg.info("Finish", time=start)

File /path/to/squidpy_env/lib/python3.9/site-packages/squidpy/_utils.py:174, in parallelize.<locals>.wrapper(*args, **kwargs)
    171 else:
    172     pbar, queue, thread = None, None, None
--> 174 res = jl.Parallel(n_jobs=n_jobs, backend=backend)(
    175     jl.delayed(runner if use_runner else callback)(
    176         *((i, cs) if use_ixs else (cs,)),
    177         *args,
    178         **kwargs,
    179         queue=queue,
    180     )
    181     for i, cs in enumerate(collections)
    182 )
    184 if thread is not None:
    185     thread.join()

File /path/to/squidpy_env/lib/python3.9/site-packages/joblib/parallel.py:1918, in Parallel.__call__(self, iterable)
   1916     output = self._get_sequential_output(iterable)
   1917     next(output)
-> 1918     return output if self.return_generator else list(output)
   1920 # Let's create an ID that uniquely identifies the current call. If the
   1921 # call is interrupted early and that the same instance is immediately
   1922 # re-used, this id will be used to prevent workers that were
   1923 # concurrently finalizing a task from the previous call to run the
   1924 # callback.
   1925 with self._lock:

File /path/to/squidpy_env/lib/python3.9/site-packages/joblib/parallel.py:1847, in Parallel._get_sequential_output(self, iterable)
   1845 self.n_dispatched_batches += 1
   1846 self.n_dispatched_tasks += 1
-> 1847 res = func(*args, **kwargs)
   1848 self.n_completed_tasks += 1
   1849 self.print_progress()

File /path/to/squidpy_env/lib/python3.9/site-packages/squidpy/im/_feature.py:118, in _calculate_image_features_helper(obs_ids, adata, img, layer, library_id, features, features_kwargs, queue, **kwargs)
    106 def _calculate_image_features_helper(
    107     obs_ids: Sequence[str],
    108     adata: AnnData,
   (...)
    115     **kwargs: Any,
    116 ) -> pd.DataFrame:
    117     features_list = []
--> 118     for crop in img.generate_spot_crops(
    119         adata, obs_names=obs_ids, library_id=library_id, return_obs=False, as_array=False, **kwargs
    120     ):
    121         if TYPE_CHECKING:
    122             assert isinstance(crop, ImageContainer)

File /path/to/squidpy_env/lib/python3.9/site-packages/squidpy/im/_container.py:839, in ImageContainer.generate_spot_crops(self, adata, spatial_key, library_id, spot_diameter_key, spot_scale, obs_names, as_array, squeeze, return_obs, **kwargs)
    837     y = int(y - self.data.attrs[Key.img.coords].y0)
    838     x = int(x - self.data.attrs[Key.img.coords].x0)
--> 839 crop = self.crop_center(y=y, x=x, radius=radius, library_id=obs_library_ids[i], **kwargs)
    840 crop.data.attrs[Key.img.obs] = obs
    841 crop = crop._maybe_as_array(as_array, squeeze=squeeze, lazy=False)

File /path/to/squidpy_env/lib/python3.9/site-packages/squidpy/im/_container.py:660, in ImageContainer.crop_center(self, y, x, radius, **kwargs)
    658 y, x = self._convert_to_pixel_space((y, x))
    659 _assert_in_range(y, 0, self.shape[0], name="height")
--> 660 _assert_in_range(x, 0, self.shape[1], name="width")
    662 if not isinstance(radius, Iterable):
    663     radius = (radius, radius)

File /path/to/squidpy_env/lib/python3.9/site-packages/squidpy/gr/_utils.py:189, in _assert_in_range(value, minn, maxx, name)
    187 def _assert_in_range(value: float, minn: float, maxx: float, *, name: str) -> None:
    188     if not (minn <= value <= maxx):
--> 189         raise ValueError(f"Expected `{name}` to be in interval `[{minn}, {maxx}]`, found `{value}`.")

ValueError: Expected `width` to be in interval `[0, 1985]`, found `2026`.

Version

squidpy==1.6.5

Also occurs when squidpy==1.6.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions