|
| 1 | +from os.path import join |
| 2 | +from spatialdata import SpatialData, to_polygons |
| 3 | +from spatialdata.models import Image2DModel, Labels2DModel, TableModel |
| 4 | +from spatialdata.transformations import ( |
| 5 | + Scale, |
| 6 | + set_transformation, |
| 7 | +) |
| 8 | +from anndata import read_zarr |
| 9 | +from tifffile import imread |
| 10 | +import zarr |
| 11 | + |
| 12 | +base_dir = join("S-1905-017737") |
| 13 | + |
| 14 | +img_path = join(base_dir, "S-1905-017737_PAS_2of2_bf.ome.tif") |
| 15 | +seg_path = join(base_dir, "S-1905-017737_PAS_2of2.ome.tif") |
| 16 | + |
| 17 | +adata_paths = { |
| 18 | + "cortical_interstitia": join(base_dir, "Cortical Interstitium.adata.zarr"), |
| 19 | + "non_globally_sclerotic_glomeruli": join(base_dir, "Glomeruli.adata.zarr"), |
| 20 | + "globally_sclerotic_glomeruli": join(base_dir, "Globally Sclerotic Glomeruli.adata.zarr"), |
| 21 | + "tubules": join(base_dir, "Tubules with Area non infinity.adata.zarr"), |
| 22 | + "arteries_arterioles": None, |
| 23 | + "interstitialfibrosis_and_tubular_atrophy": join(base_dir, "IFTA.adata.zarr"), |
| 24 | + "peritubular_capillaries": join(base_dir, "Peritubular Capillaries renamed.adata.zarr"), |
| 25 | +} |
| 26 | + |
| 27 | +# The shape of the data should be c(z)yx for 2D (3D) images |
| 28 | +img_arr = imread(img_path) |
| 29 | +seg_store = imread(seg_path, aszarr=True) |
| 30 | +seg_z = zarr.open(seg_store) |
| 31 | + |
| 32 | +def clean_adata(adata): |
| 33 | + colnames = adata.obs.columns.tolist() |
| 34 | + adata.obs = adata.obs.rename(columns=dict([ (c, c.replace(" ", "_")) for c in colnames ])) |
| 35 | + # Many of the anndata objects contain un-helpful obs indices with entirely zero values like [0, 0, 0, 0] |
| 36 | + # TODO: determine whether using 1...N+1 in these cases is correct. |
| 37 | + if adata.obs.index.unique().shape[0] == 1: |
| 38 | + adata.obs.index = range(1, adata.obs.shape[0]+1) |
| 39 | + return adata |
| 40 | + |
| 41 | +sdata = SpatialData( |
| 42 | + images={ |
| 43 | + "image": Image2DModel.parse(img_arr, scale_factors=[2, 2, 2, 2, 2]), |
| 44 | + }, |
| 45 | + tables={ |
| 46 | + f"table_{obs_type}": TableModel.parse(clean_adata(read_zarr(adata_path))) |
| 47 | + for obs_type, adata_path in adata_paths.items() |
| 48 | + if adata_path is not None |
| 49 | + } |
| 50 | +) |
| 51 | + |
| 52 | +for i, obs_type in enumerate(adata_paths.keys()): |
| 53 | + sdata[f"labels_{obs_type}"] = Labels2DModel.parse(seg_z['1'][i, :, :], scale_factors=[2, 2, 2, 2]) |
| 54 | + # Scale by a factor of 2 since we are using the second resolution from the original file. |
| 55 | + scale = Scale([2.0, 2.0], axes=("y","x")) |
| 56 | + set_transformation(sdata[f"labels_{obs_type}"], scale, to_coordinate_system="global") |
| 57 | + |
| 58 | +for labels_key in sdata.labels.keys(): |
| 59 | + shapes_key = "shapes" + labels_key[labels_key.index("_"):] |
| 60 | + sdata.shapes[shapes_key] = to_polygons(sdata.labels[labels_key]) |
| 61 | + |
| 62 | +sdata.write(join(base_dir, "sdata.zarr"), overwrite=True) |
| 63 | +print(join(base_dir, "S-1905-017737.sdata.zarr")) |
| 64 | +print("Done") |
0 commit comments