BiomedicalMachineLearning / stLearn

A novel machine learning pipeline to analyse spatial transcriptomics data
Other
176 stars 23 forks source link

st.add.image throwing error 'spatial/tissue_lowres_image.png' does not end on a valid extension' #258

Closed rialc13 closed 8 months ago

rialc13 commented 8 months ago

Hi. Thank you for developing this tool. I am noticing a weird thing when running st.add.image on my visium dataset. The first time I run the command st.add.image(adata=bdata, imgpath='brain_spatial/tissue_lowres_image.png', library_id='mouse_brain_anterior', quality='lowres', visium=True) I get the following error -

image

I re-run the above command without the 'visium=True' argument & get a similar error. I then re-run the above command (with the visium flag) & it runs successfully.

image

There is no difference in the command I'm running the 1st time & the 3rd time but it only works the 3rd time. Can you please help?

duypham2108 commented 8 months ago

The visium parameter is used in case you want to replace the image (read by scanpy.read_visium or stlearn.Read10X). Your case should be visium=False.

To explain this behavior, the first run was creating .uns['spatial'] and then you can run it successfully in the second run.

rialc13 commented 8 months ago

My raw mouse brain data did come from Visium but it was processed in R Studio & stored as brain_integrated_dataset.h5ad. (During this conversion, the spatial information is lost so I am adding the spatial information using st.add.image & st.add.positions).

In order to read this file as an anndata object in scanpy/stlearn, I am using the command bdata = scanpy.read_h5ad("brain_integrated_dataset.h5ad").

I tried running (separately) the commands st.add.image(adata=bdata, imgpath='brain_spatial/tissue_lowres_image.png', library_id='mouse_brain_anterior', quality='lowres') & st.add.image(adata=bdata, imgpath='brain_spatial/tissue_lowres_image.png', library_id='mouse_brain_anterior', quality='lowres', visium=False) but getting the same error.

I am not using either of the scanpy.read_visium or stlearn.Read10X commands.

duypham2108 commented 8 months ago

Can you run this code to see where is the problem?

from matplotlib import pyplot as plt
quality = "lowres"
scale = 1
library_id = "mouse_brain_anterior"

img = plt.imread(imgpath, 0)

adata.uns["spatial"] = {}
adata.uns["spatial"][library_id] = {}
adata.uns["spatial"][library_id]["images"] = {}
adata.uns["spatial"][library_id]["images"][quality] = img
adata.uns["spatial"][library_id]["use_quality"] = quality
adata.uns["spatial"][library_id]["scalefactors"] = {}
adata.uns["spatial"][library_id]["scalefactors"][
                    "tissue_" + quality + "_scalef"
                ] = scale
adata.uns["spatial"][library_id]["scalefactors"][
                    "spot_diameter_fullres"
                ] = spot_diameter_fullres
adata.obsm["spatial"] = adata.obs[["imagecol", "imagerow"]].values
adata.obs[["imagecol", "imagerow"]] = adata.obsm["spatial"] * scale
rialc13 commented 8 months ago

I ran your code after adding the imgpath & spot_diameter_fullres = 50 (default value) & getting the following error -

from matplotlib import pyplot as plt
quality = "lowres"
scale = 1
library_id = "mouse_brain_anterior"
imgpath = 'brain_spatial/tissue_lowres_image.png'
spot_diameter_fullres = 50

img = plt.imread(imgpath, 0)

bdata.uns["spatial"] = {}
bdata.uns["spatial"][library_id] = {}
bdata.uns["spatial"][library_id]["images"] = {}
bdata.uns["spatial"][library_id]["images"][quality] = img
bdata.uns["spatial"][library_id]["use_quality"] = quality
bdata.uns["spatial"][library_id]["scalefactors"] = {}
bdata.uns["spatial"][library_id]["scalefactors"][
                    "tissue_" + quality + "_scalef"
                ] = scale
bdata.uns["spatial"][library_id]["scalefactors"][
                    "spot_diameter_fullres"
                ] = spot_diameter_fullres
bdata.obsm["spatial"] = bdata.obs[["imagecol", "imagerow"]].values
bdata.obs[["imagecol", "imagerow"]] = bdata.obsm["spatial"] * scale
image

After running the above code, my bdata contains the following - AnnData object with n_obs × n_vars = 2696 × 3000 obs: 'orig.ident', 'nCount_Spatial', 'nFeature_Spatial', 'slice', 'region', 'nCount_SCT', 'nFeature_SCT', 'integrated_snn_res.0.8', 'seurat_clusters' var: 'features', 'SCT_features' uns: 'neighbors', 'spatial' obsm: 'X_pca', 'X_umap' varm: 'PCs' layers: 'SCT' obsp: 'distances'

rialc13 commented 8 months ago

I was able to resolve the issue by first running the command st.add.positions(adata=bdata, position_filepath='brain_spatial/tissue_positions_list.csv', scale_filepath='brain_spatial/scalefactors_json.json', quality='low') which added 'imagerow', 'imagecol' to bdata.obs & then ran the command st.add.image(adata=bdata, imgpath='brain_spatial/tissue_lowres_image.png', library_id='mouse_brain_anterior', quality='lowres', visium=False).

Earlier, I was doing the other way around (running the st.add.image command first followed by st.add.positions). From the error above, it's evident that for running the st.add.image, the anndata object needs to have the 'imagerow', 'imagecol' in adata.obs.