saezlab / liana-py

LIANA+: an all-in-one framework for cell-cell communication
http://liana-py.readthedocs.io/
GNU General Public License v3.0
169 stars 21 forks source link

Obsm 'local_scores' needs to be of one specific type when running li.mt.bivariate #147

Open dertrotl opened 1 month ago

dertrotl commented 1 month ago

Hey, first of all, thanks a lot for this great package!

However, I had some issues following your Bivariate Ligand-Receptor Relationships tutorial. When running the following code from your tutorial:

#test

adata = sc.read("kuppe_heart19.h5ad", backup_url='https://figshare.com/ndownloader/files/41501073?private_link=4744950f8768d5c8f68c')
adata.layers['counts'] = adata.X.copy()
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)

li.ut.spatial_neighbors(adata, bandwidth=200, cutoff=0.1, kernel='gaussian', set_diag=True)
li.mt.bivariate(adata,
                resource_name='consensus', # NOTE: uses HUMAN gene symbols!
                local_name='cosine', # Name of the function
                global_name="morans", # Name global function
                n_perms=100, # Number of permutations to calculate a p-value
                mask_negatives=False, # Whether to mask LowLow/NegativeNegative interactions
                add_categories=True, # Whether to add local categories to the results
                nz_prop=0.2, # Minimum expr. proportion for ligands/receptors and their subunits
                use_raw=False,
                verbose=True
                )

I get the following error:

Obsm 'local_scores' needs to be of one of np.ndarray, numpy.ma.core.MaskedArray, scipy.sparse.spmatrix, awkward.Array, h5py.Dataset, zarr.Array, zappy.base.ZappyArray, anndata.experimental.[CSC,CSR]Dataset, dask.array.Array, cupy.ndarray, or cupyx.scipy.sparse.spmatrix, not <class 'anndata._core.anndata.AnnData'>. ( see screeshot)

Thank you for your help!

image

dbdimitrov commented 1 month ago

Hi @dertrotl,

This looks like a versioning issue or perhaps a format issue with the input matrix. Can you double check if your .X matrix is a csr_matrix or alternatively numpy array?

Also, providing some info on your session could help.

Daniel

dertrotl commented 1 month ago

Hi @dbdimitrov,

thank you for your response.

I checked the format of the input matrix,

type(adata.X) scipy.sparse._csr.csr_matrix

Tried converting it like this adata.X = adata.X.toarray(), which resolved into the same error.

Some session information:

scipy version: 1.13.1
anndata version: 0.10.9
scanpy version: 1.10.3
numpy version: 1.26.4
liana version: 1.4.0
pandas version: 2.2.2
decoupler version: 1.8.0
python version: 3.10.14 | packaged by conda-forge | (main, Mar 20 2024, 12:45:18) [GCC 12.3.0]

Thanks!

dertrotl commented 1 month ago

Seems to work if one is trying not add the results to the adata object, e.g. setting inplace=False:

tt = li.mt.bivariate(adata,
                resource_name='consensus', # NOTE: uses HUMAN gene symbols!
                local_name='morans', # Name of the function
                global_name="morans", # Name global function
                n_perms=100, # Number of permutations to calculate a p-value
                mask_negatives=False, # Whether to mask LowLow/NegativeNegative interactions
                add_categories=True, # Whether to add local categories to the results
                nz_prop=0.2, # Minimum expr. proportion for ligands/receptors and their subunits
                use_raw=False,
                verbose=True,
                inplace = False
                )

Output tt is saved as tuple with tt[0] containing data frame and tt[1] an adata object.

image image

dbdimitrov commented 1 month ago

Hi @dertrotl,

Thanks a lot for raising this issue. I encountered it also myself, it seems like AnnData now enforces specific types in obsm, and one can no longer assign an AnnData object there. I will change it in next update.

Best wishes, Daniel

dbdimitrov commented 3 weeks ago

PS. tbh, I couldn't think of an elegant way to fix this such that one can save in place. Commonly, people would store a matrix in obsm, and then auxiliary information in uns, etc. I personally don't like that, rebuilding an AnnData object from this scattered data would be a pain. So, I will instead just drop the inplace parameter and would always return an AnnData with all the information in it - i.e. the one that is currently stored in obsm.

If anyone has a better idea let me know :)