squidpy icon indicating copy to clipboard operation
squidpy copied to clipboard

MVP for morpohology module

Open timtreis opened this issue 1 year ago • 2 comments

MRE:

import squidpy as sq
import spatialdata as sd
from spatialdata.datasets import raccoon
import spatialdata_plot
from scipy.stats import entropy

sdata = raccoon()

def my_func(regionmask, intensity_image):
    
    masked_values = intensity_image[regionmask]
    histogram, bin_edges = np.histogram(masked_values, bins=256, range=(0, 255))
    probabilities = histogram / np.sum(histogram)

    return entropy(probabilities, base=2)

sq.im.quantify_morphology(
    sdata,
    label="segmentation",
    image="raccoon",
    methods=["area", "perimeter", "circularity", "intensity_mean", my_func],
    split_by_channels=True,
)

image

image

Notes

  • circularity is a non-skimage method but internal method (we need a library of those, can "steal" from CellProfiler + X)
  • my_func is an external method that gets fed to skimage.measure.regionprops. We need to provide doc on how to make such method. They take in a mask of the respective cell as well as a (potentially multi-channel) intensity image (both np.ndarrays).
  • add back to adata instead, align with rest of codebase
  • now thing of how to integrate custom callables that are external to the codebase, f.e. huggingface models
  • Needs to respect transformations & deal with different scales
  • Needs notebook in squidpy-notebooks

From discussion on 2024-08-13

  • Workstreams
      1. "baseline" regionprops: what skimage has natively as functions, can query by string
      1. "non-baseline" regionprops: other metrics we can "steal" from CellProfiler etc and make available by string internally
      • f.e. take math from https://github.com/CellProfiler/CellProfiler/blob/main/src/frontend/cellprofiler/modules/measuregranularity.py#L432
      1. feed in methods that take in mask / intensity image
      1. test performance of regionprops on actual data - does it work at scale at all?
      • if not, can we hijack the method and parallelize across chunks (parallel io) and collect
      • can we lazy-compute? dask?
      1. respect transformations and datatree "zoom" - which matches, what does the user want?
      1. my_func wrapper for model inference, f.e. from some HF-model?
      • download model etc?
      • they might require specific resolution, might have to scale all cells because area contains info

timtreis avatar Aug 07 '24 21:08 timtreis

Codecov Report

Attention: Patch coverage is 20.33898% with 47 lines in your changes missing coverage. Please review.

Project coverage is 69.52%. Comparing base (4a632d6) to head (bbecec3). Report is 5 commits behind head on main.

Files Patch % Lines
src/squidpy/im/_feature.py 20.33% 47 Missing :warning:
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #866      +/-   ##
==========================================
- Coverage   69.99%   69.52%   -0.47%     
==========================================
  Files          39       39              
  Lines        5532     5667     +135     
  Branches     1037     1063      +26     
==========================================
+ Hits         3872     3940      +68     
- Misses       1367     1429      +62     
- Partials      293      298       +5     
Files Coverage Δ
src/squidpy/im/_feature.py 51.81% <20.33%> (-37.08%) :arrow_down:

... and 2 files with indirect coverage changes

codecov-commenter avatar Aug 07 '24 21:08 codecov-commenter

I had to remove the code that called the label function from skimage as it was creating additional labels that we cannot trace back to the original labels.

npeschke avatar Aug 16 '24 13:08 npeschke

Superseded by https://github.com/scverse/squidpy/pull/982

timtreis avatar Mar 28 '25 22:03 timtreis