Skip to content

Commit 31734e8

Browse files
committed
adding simple spatial capability
1 parent 7c5f836 commit 31734e8

File tree

2 files changed

+76
-2
lines changed

2 files changed

+76
-2
lines changed

panopticon/spatial.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import pandas as pd
2+
import numpy as np
3+
import matplotlib.pyplot as plt
4+
5+
def get_labels_and_polys(tif_file):
6+
from panopticon.utilities import import_check
7+
exit_code = import_check(
8+
"tifffile", 'pip install tifffile')
9+
if exit_code != 0:
10+
return
11+
exit_code = import_check(
12+
"stardist", 'pip install stardist')
13+
if exit_code != 0:
14+
return
15+
from tifffile import imread, imwrite, imshow
16+
from stardist.models import StarDist2D
17+
img = imread(tif_file)
18+
img = img.swapaxes(0,2) #Assumes to be CXY, we switch to YXC
19+
model = StarDist2D.from_pretrained('2D_versatile_he')
20+
21+
img = img/255
22+
labels, polys =
23+
labels, polys = model.predict_instances_big(img, axes='YXC', block_size=4096, prob_thresh=0.01,nms_thresh=0.001, min_overlap=128, context=128, normalizer=None, n_tiles=(4,4,1))
24+
25+
def get_gdf(labels, polys):
26+
exit_code = import_check(
27+
"geopandas", 'pip install geopandas')
28+
if exit_code != 0:
29+
return
30+
import geopandas as gpd
31+
32+
# Creating a list to store Polygon geometries
33+
geometries = []
34+
35+
# Iterating through each nuclei in the 'polys' DataFrame
36+
for nuclei in range(len(polys['coord'])):
37+
38+
# Extracting coordinates for the current nuclei and converting them to (y, x) format
39+
coords = [(y, x) for x, y in zip(polys['coord'][nuclei][0], polys['coord'][nuclei][1])]
40+
41+
# Creating a Polygon geometry from the coordinates
42+
geometries.append(Polygon(coords))
43+
44+
# Creating a GeoDataFrame using the Polygon geometries
45+
gdf = gpd.GeoDataFrame(geometry=geometries)
46+
gdf['id'] = [f"ID_{i+1}" for i, _ in enumerate(gdf.index)]
47+
return gdf
48+

scripts/panopticon

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,26 @@ def combine_looms(input_looms, output_loom, output_type='loom'):
4545
'Whitelist a gene to include (will blacklist all other genes). Intended for getting antibody counts from empty droplets, where other types of counts are not needed. Usage --whitelist_gene Hash123',
4646
multiple=True,
4747
default=None)
48+
@click.option(
49+
'--exclude_feature_type',
50+
help=
51+
'Exclude a feature type from conversion (e.g. "Gene Expression", "Peaks", etc.). Usage --exclude_feature_type Peaks',
52+
multiple=True,
53+
default=None)
4854
@click.option(
4955
'--write_chunked',
5056
help='flag to write output loom in chunked fashion (to reduce memory burden)',
5157
is_flag=True)
52-
def convert_10x_h5(h5file, output_loom, label, convert_to_ca, whitelist_gene,write_chunked):
58+
def convert_10x_h5(h5file, output_loom, label, convert_to_ca, whitelist_gene,write_chunked, exclude_feature_type):
5359
from panopticon.utilities import convert_10x_h5
5460
convert_10x_h5(h5file,
5561
output_loom,
5662
label[0],
5763
label[1],
5864
genes_as_ca=convert_to_ca,
5965
gene_whitelist=whitelist_gene,
60-
write_chunked=write_chunked)
66+
write_chunked=write_chunked,
67+
exclude_feature_type=exclude_feature_type)
6168

6269

6370
@cli.command(
@@ -136,6 +143,25 @@ def reaptec(fastq_dir, cellranger_output_dir, star_reference_dir,
136143
reaptec_main(fastq_dir, cellranger_output_dir, star_reference_dir,
137144
reference_url, genome_url)
138145

146+
@cli.command(
147+
help="Generating a geopandas dataframe with location of called nuclei")
148+
@click.argument('tif_file', type=click.Path(exists=True),nargs=1)
149+
@click.argument('output_file_name',nargs=1)
150+
def generate_segmentation_gdf(tif_file, output_file_name):
151+
from panopticon.spatial import get_labels_and_polys, get_gdf
152+
if output_file_name.split('.')[-1] not in ['pkl','csv','parquet']:
153+
raise Exception("output_file_name should end in one of ['csv','pkl','parquet']")
154+
labels, polys = get_labels_and_polys(tif_file)
155+
gdf = get_gdf(labels, polys)
156+
if output_file_name.endswith('.pkl'):
157+
gdf.to_pickle(output_file_name)
158+
elif output_file_name.endswith('.csv'):
159+
gdf.to_csv(output_file_name)
160+
elif output_file_name.endswith('.parquet'):
161+
gdf.to_parquet(output_file_name)
162+
163+
164+
139165

140166
if __name__ == '__main__':
141167
cli()

0 commit comments

Comments
 (0)