Skip to content

Commit 6c1c100

Browse files
authored
Merge pull request #39 from computational-cell-analytics/object_measures_from_json
Calculate object measures based on JSON file
2 parents 476e1fe + 865534a commit 6c1c100

File tree

5 files changed

+168
-3
lines changed

5 files changed

+168
-3
lines changed

flamingo_tools/measurements.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import os
33
from concurrent import futures
44
from functools import partial
5-
from typing import Optional
5+
from typing import List, Optional
66

77
import numpy as np
88
import pandas as pd
@@ -12,6 +12,7 @@
1212

1313
from .file_utils import read_image_data
1414
from .segmentation.postprocessing import compute_table_on_the_fly
15+
import flamingo_tools.s3_utils as s3_utils
1516

1617

1718
def _measure_volume_and_surface(mask, resolution):
@@ -175,6 +176,8 @@ def compute_object_measures(
175176
resolution: float = 0.38,
176177
force: bool = False,
177178
feature_set: str = "default",
179+
s3_flag: bool = False,
180+
component_list: List[int] = [],
178181
) -> None:
179182
"""Compute simple intensity and morphology measures for each segmented cell in a segmentation.
180183
@@ -201,9 +204,17 @@ def compute_object_measures(
201204
# First, we load the pre-computed segmentation table from MoBIE.
202205
if segmentation_table_path is None:
203206
table = None
207+
elif s3_flag:
208+
seg_table, fs = s3_utils.get_s3_path(segmentation_table_path)
209+
with fs.open(seg_table, 'r') as f:
210+
table = pd.read_csv(f, sep="\t")
204211
else:
205212
table = pd.read_csv(segmentation_table_path, sep="\t")
206213

214+
# filter table with largest component
215+
if len(component_list) != 0 and "component_labels" in table.columns:
216+
table = table[table['component_labels'].isin(component_list)]
217+
207218
# Then, open the volumes.
208219
image = read_image_data(image_path, image_key)
209220
segmentation = read_image_data(segmentation_path, segmentation_key)

reproducibility/block_extraction/repro_block_extraction.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88

99
def repro_block_extraction(
10-
ddict: dict,
10+
json_file: str,
1111
output_dir: str,
1212
s3_credentials: Optional[str] = None,
1313
s3_bucket_name: Optional[str] = None,
@@ -17,7 +17,7 @@ def repro_block_extraction(
1717
tif_flag = True
1818
input_key = "s0"
1919

20-
with open(ddict, 'r') as myfile:
20+
with open(json_file, 'r') as myfile:
2121
data = myfile.read()
2222
param_dicts = json.loads(data)
2323

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[
2+
{
3+
"cochlea": "M_AMD_OTOF1_L",
4+
"image_channel": [
5+
"Apha"
6+
],
7+
"segmentation_channel": "IHC_v2",
8+
"component_list": [
9+
1,
10+
20
11+
]
12+
},
13+
{
14+
"cochlea": "M_AMD_OTOF2_L",
15+
"image_channel": [
16+
"Apha"
17+
],
18+
"segmentation_channel": "IHC_v2",
19+
"component_list": [
20+
1,
21+
2
22+
]
23+
}
24+
]
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
[
2+
{
3+
"cochlea": "M_LR_000144_L",
4+
"image_channel": [
5+
"PV_resized",
6+
"GFP_resized"
7+
],
8+
"segmentation_channel": "SGN_resized_v2",
9+
"component_list": [
10+
1
11+
]
12+
},
13+
{
14+
"cochlea": "M_LR_000145_L",
15+
"image_channel": [
16+
"PV_resized",
17+
"GFP_resized"
18+
],
19+
"segmentation_channel": "SGN_resized_v2",
20+
"component_list": [
21+
1
22+
]
23+
},
24+
{
25+
"cochlea": "M_LR_000151_R",
26+
"image_channel": [
27+
"PV_resized",
28+
"GFP_resized"
29+
],
30+
"segmentation_channel": "SGN_resized_v2",
31+
"component_list": [
32+
1
33+
]
34+
},
35+
{
36+
"cochlea": "M_LR_000155_L",
37+
"image_channel": [
38+
"PV_resized",
39+
"GFP_resized"
40+
],
41+
"segmentation_channel": "SGN_resized_v2",
42+
"component_list": [
43+
1
44+
]
45+
}
46+
]
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import argparse
2+
import json
3+
import os
4+
from typing import Optional
5+
6+
import flamingo_tools.s3_utils as s3_utils
7+
from flamingo_tools.measurements import compute_object_measures
8+
9+
10+
def repro_object_measures(
11+
json_file: str,
12+
output_dir: str,
13+
s3_credentials: Optional[str] = None,
14+
s3_bucket_name: Optional[str] = None,
15+
s3_service_endpoint: Optional[str] = None,
16+
):
17+
s3_flag = True
18+
input_key = "s0"
19+
20+
with open(json_file, 'r') as myfile:
21+
data = myfile.read()
22+
param_dicts = json.loads(data)
23+
24+
for dic in param_dicts:
25+
cochlea = dic["cochlea"]
26+
image_channels = dic["image_channel"] if isinstance(dic["image_channel"], list) else [dic["image_channel"]]
27+
seg_channel = dic["segmentation_channel"]
28+
component_list = dic["component_list"]
29+
print(f"Processing cochlea {cochlea}")
30+
31+
for img_channel in image_channels:
32+
33+
print(f"Processing image channel {img_channel}")
34+
cochlea_str = "-".join(cochlea.split("_"))
35+
img_str = "-".join(img_channel.split("_"))
36+
seg_str = "-".join(seg_channel.split("_"))
37+
output_table_path = os.path.join(output_dir, f"{cochlea_str}_{img_str}_{seg_str}_object-measures.tsv")
38+
39+
img_s3 = f"{cochlea}/images/ome-zarr/{img_channel}.ome.zarr"
40+
seg_s3 = f"{cochlea}/images/ome-zarr/{seg_channel}.ome.zarr"
41+
seg_table_s3 = f"{cochlea}/tables/{seg_channel}/default.tsv"
42+
43+
img_path, fs = s3_utils.get_s3_path(img_s3, bucket_name=s3_bucket_name,
44+
service_endpoint=s3_service_endpoint, credential_file=s3_credentials)
45+
seg_path, fs = s3_utils.get_s3_path(seg_s3, bucket_name=s3_bucket_name,
46+
service_endpoint=s3_service_endpoint, credential_file=s3_credentials)
47+
48+
compute_object_measures(
49+
image_path=img_path,
50+
segmentation_path=seg_path,
51+
segmentation_table_path=seg_table_s3,
52+
output_table_path=output_table_path,
53+
image_key=input_key,
54+
segmentation_key=input_key,
55+
s3_flag=s3_flag,
56+
component_list=component_list)
57+
58+
59+
def main():
60+
parser = argparse.ArgumentParser(
61+
description="Script to extract region of interest (ROI) block around center coordinate.")
62+
63+
parser.add_argument('-i', '--input', type=str, required=True, help="Input JSON dictionary.")
64+
parser.add_argument('-o', "--output", type=str, required=True, help="Output directory.")
65+
66+
parser.add_argument("--s3_credentials", type=str, default=None,
67+
help="Input file containing S3 credentials. "
68+
"Optional if AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY were exported.")
69+
parser.add_argument("--s3_bucket_name", type=str, default=None,
70+
help="S3 bucket name. Optional if BUCKET_NAME was exported.")
71+
parser.add_argument("--s3_service_endpoint", type=str, default=None,
72+
help="S3 service endpoint. Optional if SERVICE_ENDPOINT was exported.")
73+
74+
args = parser.parse_args()
75+
76+
repro_object_measures(
77+
args.input, args.output,
78+
args.s3_credentials, args.s3_bucket_name, args.s3_service_endpoint,
79+
)
80+
81+
82+
if __name__ == "__main__":
83+
84+
main()

0 commit comments

Comments
 (0)