Skip to content

Commit 88c78e9

Browse files
authored
Merge pull request #71 from fmi-basel/dev-nar
Clean up config file parameters
2 parents 98c46d5 + f560c8e commit 88c78e9

File tree

7 files changed

+42
-39
lines changed

7 files changed

+42
-39
lines changed

scripts/configs/config.ini.example

+1-2
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,8 @@ membrane_seg_channel = ${00BuildExperiment.round_R0:membrane_seg_channel}
3232
[01FeatureExtraction]
3333
excluded_plates = day2
3434
excluded_wells = C02
35-
ovr_channel = C01
36-
name_ovr = regionprops_ovr_
3735
iop_cutoff = 0.6
36+
measure_morphology = True
3837

3938
[02OrganoidLinking]
4039
iou_cutoff = 0.2

scripts/prefect/01_feature_extraction.py

+18-13
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
parse_spacing,
3333
summary_csv_path,
3434
spacing_anisotropy_tuple,
35+
str2bool
3536
)
3637
from scmultiplex.features.FeatureExtraction import (
3738
extract_organoid_features,
@@ -58,10 +59,10 @@ def load_task(exp_path: str, excluded_plates: List[str], excluded_wells: List[st
5859

5960

6061
@task()
61-
def well_feature_extraction_ovr_task(well: WellRecord, ovr_channel: str, name_ovr: str):
62+
def well_feature_extraction_ovr_task(well: WellRecord, org_seg_ch: str):
6263
extract_well_features(
6364
well=well,
64-
ovr_channel=ovr_channel,
65+
ovr_channel=org_seg_ch,
6566
)
6667
return
6768

@@ -92,8 +93,8 @@ def get_organoids(
9293

9394
@task()
9495
def organoid_feature_extraction_and_linking_task(
95-
organoid, nuc_ending: str, mem_ending: str, mask_ending: str, spacing: List[float],
96-
org_seg_ch, nuc_seg_ch, mem_seg_ch, ovr_channel, iop_cutoff):
96+
organoid, nuc_ending: str, mem_ending: str, mask_ending: str, spacing: List[float], measure_morphology,
97+
org_seg_ch, nuc_seg_ch, mem_seg_ch, iop_cutoff):
9798

9899
set_spacing(spacing)
99100
extract_organoid_features(
@@ -102,14 +103,14 @@ def organoid_feature_extraction_and_linking_task(
102103
mem_ending=mem_ending,
103104
mask_ending=mask_ending,
104105
spacing=tuple(spacing),
105-
measure_morphology=True,
106+
measure_morphology=measure_morphology,
106107
organoid_seg_channel=org_seg_ch,
107108
nuclear_seg_channel=nuc_seg_ch,
108109
membrane_seg_channel=mem_seg_ch,
109110
)
110111
link_nuc_to_membrane(
111112
organoid=organoid,
112-
ovr_channel=ovr_channel,
113+
ovr_channel=org_seg_ch,
113114
nuc_ending=nuc_ending,
114115
mask_ending=mask_ending,
115116
mem_ending=mem_ending,
@@ -128,21 +129,20 @@ def run_flow(r_params, cpus):
128129
exp_path = Parameter("exp_path")
129130
excluded_plates = Parameter("excluded_plates")
130131
excluded_wells = Parameter("excluded_wells")
131-
ovr_channel = Parameter("ovr_channel")
132132
mask_ending = Parameter("mask_ending")
133133
nuc_ending = Parameter("nuc_ending")
134134
mem_ending = Parameter("mem_ending")
135-
name_ovr = Parameter("name_ovr")
136135
iop_cutoff = Parameter("iop_cutoff")
137136
spacing = Parameter("spacing")
137+
measure_morphology = Parameter("measure_morphology")
138138
org_seg_ch = Parameter("org_seg_ch")
139139
nuc_seg_ch = Parameter("nuc_seg_ch")
140140
mem_seg_ch = Parameter("mem_seg_ch")
141141

142142
exp, wells = load_task(exp_path, excluded_plates, excluded_wells)
143143

144144
wfeo_t = well_feature_extraction_ovr_task.map(
145-
wells, unmapped(ovr_channel), unmapped(name_ovr)
145+
wells, unmapped(org_seg_ch)
146146
)
147147

148148
organoids = get_organoids(exp, mask_ending, excluded_plates, excluded_wells, upstream_tasks = [wfeo_t])
@@ -153,10 +153,10 @@ def run_flow(r_params, cpus):
153153
unmapped(mem_ending),
154154
unmapped(mask_ending),
155155
unmapped(spacing),
156+
unmapped(measure_morphology),
156157
unmapped(org_seg_ch),
157158
unmapped(nuc_seg_ch),
158159
unmapped(mem_seg_ch),
159-
unmapped(ovr_channel),
160160
unmapped(iop_cutoff),
161161
upstream_tasks = [organoids],
162162
)
@@ -174,12 +174,11 @@ def get_config_params(config_file_path):
174174

175175
round_names = get_round_names(config_file_path)
176176
config_params = {
177-
'ovr_channel': ('01FeatureExtraction', 'ovr_channel'),
178-
'name_ovr': ('01FeatureExtraction', 'name_ovr'),
179177
'mask_ending': ('00BuildExperiment', 'mask_ending'),
178+
'measure_morphology': ('01FeatureExtraction', 'measure_morphology'),
180179
}
181180
common_params = get_workflow_params(config_file_path, config_params)
182-
181+
183182
compute_param = {
184183
'excluded_plates': (
185184
commasplit,[
@@ -196,11 +195,17 @@ def get_config_params(config_file_path):
196195
('01FeatureExtraction', 'iop_cutoff')
197196
]
198197
),
198+
'measure_morphology': (
199+
str2bool,[
200+
('01FeatureExtraction', 'measure_morphology')
201+
]
202+
),
199203
'spacing': (
200204
parse_spacing,[
201205
('00BuildExperiment', 'spacing')
202206
]
203207
),
208+
204209
}
205210
common_params.update(compute_workflow_params(config_file_path, compute_param))
206211

scripts/prefect/02_organoid_multiplex.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ def get_wells(exp: Experiment, excluded_plates: List[str], excluded_wells: List[
5252
return exclude_conditions(exp, excluded_plates, excluded_wells)
5353

5454
@task()
55-
def link_organoids_and_get_stats_task(well, ovr_channel, folder_name, R0, RX, seg_name, RX_name, iou_cutoff, names):
55+
def link_organoids_and_get_stats_task(well, org_seg_ch, folder_name, R0, RX, seg_name, RX_name, iou_cutoff, names):
5656
link_organoids(
5757
well=well,
58-
ovr_channel=ovr_channel,
58+
ovr_channel=org_seg_ch,
5959
folder_name=folder_name,
6060
R0=R0,
6161
RX=RX,
@@ -69,7 +69,7 @@ def link_organoids_and_get_stats_task(well, ovr_channel, folder_name, R0, RX, se
6969
RX=RX,
7070
iou_cutoff=iou_cutoff,
7171
names=names,
72-
ovr_channel=ovr_channel,
72+
ovr_channel=org_seg_ch,
7373
logger=prefect.context.get("logger"),
7474
)
7575
return
@@ -87,7 +87,7 @@ def run_flow(r_params, cpus):
8787
excluded_plates = Parameter("excluded_plates")
8888
excluded_wells = Parameter("excluded_wells")
8989
iou_cutoff = Parameter("iou_cutoff")
90-
ovr_channel = Parameter("ovr_channel")
90+
org_seg_ch = Parameter("org_seg_ch")
9191

9292
R0, RX = load_exps(R0_path, RX_path)
9393
names = get_names(RX_name)
@@ -100,7 +100,7 @@ def run_flow(r_params, cpus):
100100

101101
link_organoids_and_get_stats_task.map(
102102
wells,
103-
unmapped(ovr_channel),
103+
unmapped(org_seg_ch),
104104
unmapped(folder_name),
105105
unmapped(R0),
106106
unmapped(RX),
@@ -125,10 +125,6 @@ def get_config_params(config_file_path):
125125
if len(round_names) < 2:
126126
raise RuntimeError('At least two rounds are required to perform organoid linking')
127127
rounds_tobelinked = round_names[1:]
128-
config_params = {
129-
'ovr_channel': ('01FeatureExtraction', 'ovr_channel'),
130-
}
131-
common_params = get_workflow_params(config_file_path, config_params)
132128

133129
compute_param = {
134130
'excluded_plates': (
@@ -153,11 +149,16 @@ def get_config_params(config_file_path):
153149
]
154150
),
155151
}
156-
common_params.update(compute_workflow_params(config_file_path, compute_param))
152+
common_params = compute_workflow_params(config_file_path, compute_param)
157153

158154
round_tobelinked_params = {}
159155
for ro in rounds_tobelinked:
156+
config_params = {
157+
'org_seg_ch': ('00BuildExperiment.round_%s' % ro, 'organoid_seg_channel'),
158+
}
160159
rp = common_params.copy()
160+
rp.update(get_workflow_params(config_file_path, config_params))
161+
161162
rp['RX_name'] = ro
162163
compute_param = {
163164
'RX_path': (

scripts/prefect/03_nuclear_multiplex.py

+2-9
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,9 @@ def get_organoids_task(exp: Experiment, exlude_plates: List[str]):
6060

6161

6262
@task()
63-
def link_nuclei_task(organoid, ovr_channel, segname, rx_name, RX, z_anisotropy, org_seg_ch, nuc_seg_ch):
63+
def link_nuclei_task(organoid, segname, rx_name, RX, z_anisotropy, org_seg_ch, nuc_seg_ch):
6464
link_nuclei(
6565
organoid=organoid,
66-
ovr_channel=ovr_channel,
6766
segname=segname,
6867
rx_name=rx_name,
6968
RX=RX,
@@ -83,7 +82,6 @@ def run_flow(r_params, cpus):
8382
excluded_plates = Parameter("excluded_plates")
8483
excluded_wells = Parameter("excluded_wells")
8584
nuc_ending = Parameter("nuc_ending")
86-
ovr_channel = Parameter("ovr_channel")
8785
spacing = Parameter("spacing")
8886
org_seg_ch = Parameter("org_seg_ch")
8987
nuc_seg_ch = Parameter("nuc_seg_ch")
@@ -95,7 +93,6 @@ def run_flow(r_params, cpus):
9593

9694
link_nuclei_task.map(
9795
r0_organoids,
98-
unmapped(ovr_channel),
9996
unmapped(nuc_ending),
10097
unmapped(rx_name),
10198
unmapped(RX),
@@ -119,10 +116,6 @@ def get_config_params(config_file_path):
119116
if len(round_names) < 2:
120117
raise RuntimeError('At least two rounds are required to perform organoid linking')
121118
rounds_tobelinked = round_names[1:]
122-
config_params = {
123-
'ovr_channel': ('01FeatureExtraction', 'ovr_channel'),
124-
}
125-
common_params = get_workflow_params(config_file_path, config_params)
126119

127120
compute_param = {
128121
'excluded_plates': (
@@ -147,7 +140,7 @@ def get_config_params(config_file_path):
147140
]
148141
),
149142
}
150-
common_params.update(compute_workflow_params(config_file_path, compute_param))
143+
common_params = compute_workflow_params(config_file_path, compute_param)
151144

152145
# use same z-anisotropy as used during feature extraction
153146
parsed_spacing = common_params['spacing']

src/scmultiplex/config.py

+4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ def commasplit(cstring):
5454
return cstring.split(',')
5555

5656

57+
def str2bool(bstring):
58+
return bstring.lower() in ('true',)
59+
60+
5761
def parse_spacing(spacing):
5862
return tuple(float(v) for v in commasplit(spacing))
5963

src/scmultiplex/features/feature_wrapper.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -242,13 +242,13 @@ def get_morphology_measurements(labeled_obj, img_shape, spacing, is_2D, min_area
242242
"is_touching_border_z": is_touching_border_z(
243243
labeled_obj, img_shape=img_shape
244244
),
245-
"volume_pix": labeled_obj["area"],
246245
"surface_area": labeled_obj["surface_area_marchingcube"],
247246
}
248247
morphology_measurements.update(morphology_3d_only)
249248

250249
return morphology_measurements
251250

251+
252252
def get_coordinates(labeled_obj, spacing, is_2D):
253253
coordinate_measurements = {
254254
"x_pos_pix": labeled_obj["centroid"][-1],
@@ -259,7 +259,8 @@ def get_coordinates(labeled_obj, spacing, is_2D):
259259
coordinate_measurements_3D = {
260260
"z_pos_pix_scaled": labeled_obj["centroid"][-3],
261261
"z_pos_pix_img": labeled_obj["centroid"][-3]
262-
/ spacing_anisotropy_scalar(spacing)
262+
/ spacing_anisotropy_scalar(spacing),
263+
"volume_pix": labeled_obj["area"]
263264
}
264265
coordinate_measurements.update(coordinate_measurements_3D)
265266

src/scmultiplex/linking/NucleiLinking.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def load_linking_data(organoid: OrganoidRecord, rx_name: str, org_seg_ch):
2929
return link_org, link_org_dict
3030

3131

32-
def link_nuclei(organoid, ovr_channel, segname, rx_name, RX, z_anisotropy, org_seg_ch, nuc_seg_ch):
32+
def link_nuclei(organoid, segname, rx_name, RX, z_anisotropy, org_seg_ch, nuc_seg_ch):
3333
R0_obj = organoid.organoid_id
3434
R0_id = int(R0_obj.rpartition("_")[2])
3535
well_id = organoid.well.well_id
@@ -45,7 +45,7 @@ def link_nuclei(organoid, ovr_channel, segname, rx_name, RX, z_anisotropy, org_s
4545
if R0_df_org["abs_min"][0] != 0:
4646
try:
4747
R0_df = organoid.get_measurement("regionprops_nuc_{}".format(nuc_seg_ch))
48-
R0_raw = organoid.get_raw_data(ovr_channel)
48+
R0_raw = organoid.get_raw_data(org_seg_ch)
4949
R0_seg = organoid.get_segmentation(segname)
5050
except Exception as e:
5151
print(e)
@@ -64,7 +64,7 @@ def link_nuclei(organoid, ovr_channel, segname, rx_name, RX, z_anisotropy, org_s
6464
RX.plates[plate_id]
6565
.wells[well_id]
6666
.organoids[RX_obj]
67-
.get_raw_data(ovr_channel)
67+
.get_raw_data(org_seg_ch)
6868
)
6969
RX_seg = (
7070
RX.plates[plate_id]

0 commit comments

Comments
 (0)