celldetective 1.1.1.post3__py3-none-any.whl → 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- celldetective/__init__.py +2 -1
- celldetective/__main__.py +17 -0
- celldetective/extra_properties.py +62 -34
- celldetective/gui/__init__.py +1 -0
- celldetective/gui/analyze_block.py +2 -1
- celldetective/gui/classifier_widget.py +18 -10
- celldetective/gui/control_panel.py +57 -6
- celldetective/gui/layouts.py +14 -11
- celldetective/gui/neighborhood_options.py +21 -13
- celldetective/gui/plot_signals_ui.py +39 -11
- celldetective/gui/process_block.py +413 -95
- celldetective/gui/retrain_segmentation_model_options.py +17 -4
- celldetective/gui/retrain_signal_model_options.py +106 -6
- celldetective/gui/signal_annotator.py +110 -30
- celldetective/gui/signal_annotator2.py +2708 -0
- celldetective/gui/signal_annotator_options.py +3 -1
- celldetective/gui/survival_ui.py +15 -6
- celldetective/gui/tableUI.py +248 -43
- celldetective/io.py +598 -416
- celldetective/measure.py +919 -969
- celldetective/models/pair_signal_detection/blank +0 -0
- celldetective/neighborhood.py +482 -340
- celldetective/preprocessing.py +81 -61
- celldetective/relative_measurements.py +648 -0
- celldetective/scripts/analyze_signals.py +1 -1
- celldetective/scripts/measure_cells.py +28 -8
- celldetective/scripts/measure_relative.py +103 -0
- celldetective/scripts/segment_cells.py +5 -5
- celldetective/scripts/track_cells.py +4 -1
- celldetective/scripts/train_segmentation_model.py +23 -18
- celldetective/scripts/train_signal_model.py +33 -0
- celldetective/segmentation.py +67 -29
- celldetective/signals.py +402 -8
- celldetective/tracking.py +8 -2
- celldetective/utils.py +144 -12
- {celldetective-1.1.1.post3.dist-info → celldetective-1.2.0.dist-info}/METADATA +8 -8
- {celldetective-1.1.1.post3.dist-info → celldetective-1.2.0.dist-info}/RECORD +42 -38
- {celldetective-1.1.1.post3.dist-info → celldetective-1.2.0.dist-info}/WHEEL +1 -1
- tests/test_segmentation.py +1 -1
- {celldetective-1.1.1.post3.dist-info → celldetective-1.2.0.dist-info}/LICENSE +0 -0
- {celldetective-1.1.1.post3.dist-info → celldetective-1.2.0.dist-info}/entry_points.txt +0 -0
- {celldetective-1.1.1.post3.dist-info → celldetective-1.2.0.dist-info}/top_level.txt +0 -0
celldetective/preprocessing.py
CHANGED
|
@@ -15,8 +15,6 @@ from gc import collect
|
|
|
15
15
|
from lmfit import Parameters, Model, models
|
|
16
16
|
import tifffile.tifffile as tiff
|
|
17
17
|
|
|
18
|
-
from tifffile import imwrite
|
|
19
|
-
|
|
20
18
|
def estimate_background_per_condition(experiment, threshold_on_std=1, well_option='*', target_channel="channel_name", frame_range=[0,5], mode="timeseries", activation_protocol=[['gauss',2],['std',4]], show_progress_per_pos=False, show_progress_per_well=True):
|
|
21
19
|
|
|
22
20
|
"""
|
|
@@ -98,53 +96,65 @@ def estimate_background_per_condition(experiment, threshold_on_std=1, well_optio
|
|
|
98
96
|
for l,pos_path in enumerate(tqdm(positions, disable=not show_progress_per_pos)):
|
|
99
97
|
|
|
100
98
|
stack_path = get_position_movie_path(pos_path, prefix=movie_prefix)
|
|
99
|
+
if stack_path is not None:
|
|
100
|
+
len_movie_auto = auto_load_number_of_frames(stack_path)
|
|
101
|
+
if len_movie_auto is not None:
|
|
102
|
+
len_movie = len_movie_auto
|
|
103
|
+
img_num_channels = _get_img_num_per_channel(channel_indices, int(len_movie), nbr_channels)
|
|
101
104
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
frames = load_frames(img_num_channels[0,frame_range[0]:frame_range[1]], stack_path, normalize_input=False)
|
|
105
|
-
frames = np.moveaxis(frames, -1, 0).astype(float)
|
|
106
|
-
|
|
107
|
-
for i in range(len(frames)):
|
|
108
|
-
if np.all(frames[i].flatten()==0):
|
|
109
|
-
frames[i,:,:] = np.nan
|
|
110
|
-
|
|
111
|
-
frame_mean = np.nanmean(frames, axis=0)
|
|
112
|
-
|
|
113
|
-
frame = frame_mean.copy().astype(float)
|
|
114
|
-
std_frame = filter_image(frame.copy(),filters=activation_protocol)
|
|
115
|
-
edge = estimate_unreliable_edge(activation_protocol)
|
|
116
|
-
mask = threshold_image(std_frame, threshold_on_std, np.inf, foreground_value=1, edge_exclusion=edge)
|
|
117
|
-
frame[np.where(mask.astype(int)==1)] = np.nan
|
|
118
|
-
|
|
119
|
-
elif mode=="tiles":
|
|
105
|
+
if mode=="timeseries":
|
|
120
106
|
|
|
121
|
-
|
|
122
|
-
|
|
107
|
+
frames = load_frames(img_num_channels[0,frame_range[0]:frame_range[1]], stack_path, normalize_input=False)
|
|
108
|
+
frames = np.moveaxis(frames, -1, 0).astype(float)
|
|
123
109
|
|
|
124
|
-
|
|
125
|
-
|
|
110
|
+
for i in range(len(frames)):
|
|
111
|
+
if np.all(frames[i].flatten()==0):
|
|
112
|
+
frames[i,:,:] = np.nan
|
|
126
113
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
continue
|
|
132
|
-
|
|
133
|
-
f = frames[i].copy()
|
|
134
|
-
std_frame = filter_image(f.copy(),filters=activation_protocol)
|
|
114
|
+
frame_mean = np.nanmean(frames, axis=0)
|
|
115
|
+
|
|
116
|
+
frame = frame_mean.copy().astype(float)
|
|
117
|
+
std_frame = filter_image(frame.copy(),filters=activation_protocol)
|
|
135
118
|
edge = estimate_unreliable_edge(activation_protocol)
|
|
136
119
|
mask = threshold_image(std_frame, threshold_on_std, np.inf, foreground_value=1, edge_exclusion=edge)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
120
|
+
frame[np.where(mask.astype(int)==1)] = np.nan
|
|
121
|
+
|
|
122
|
+
elif mode=="tiles":
|
|
123
|
+
|
|
124
|
+
frames = load_frames(img_num_channels[0,:], stack_path, normalize_input=False).astype(float)
|
|
125
|
+
frames = np.moveaxis(frames, -1, 0).astype(float)
|
|
126
|
+
|
|
127
|
+
new_frames = []
|
|
128
|
+
for i in range(len(frames)):
|
|
129
|
+
|
|
130
|
+
if np.all(frames[i].flatten()==0):
|
|
131
|
+
empty_frame = np.zeros_like(frames[i])
|
|
132
|
+
empty_frame[:,:] = np.nan
|
|
133
|
+
new_frames.append(empty_frame)
|
|
134
|
+
continue
|
|
135
|
+
|
|
136
|
+
f = frames[i].copy()
|
|
137
|
+
std_frame = filter_image(f.copy(),filters=activation_protocol)
|
|
138
|
+
edge = estimate_unreliable_edge(activation_protocol)
|
|
139
|
+
mask = threshold_image(std_frame, threshold_on_std, np.inf, foreground_value=1, edge_exclusion=edge)
|
|
140
|
+
f[np.where(mask.astype(int)==1)] = np.nan
|
|
141
|
+
new_frames.append(f.copy())
|
|
142
|
+
|
|
143
|
+
frame = np.nanmedian(new_frames, axis=0)
|
|
144
|
+
else:
|
|
145
|
+
print(f'Stack not found for position {pos_path}...')
|
|
146
|
+
frame = []
|
|
141
147
|
|
|
142
148
|
# store
|
|
143
149
|
frame_mean_per_position.append(frame)
|
|
144
150
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
151
|
+
try:
|
|
152
|
+
background = np.nanmedian(frame_mean_per_position,axis=0)
|
|
153
|
+
backgrounds.append({"bg": background, "well": well_path})
|
|
154
|
+
print(f"Background successfully computed for well {well_name}...")
|
|
155
|
+
except Exception as e:
|
|
156
|
+
print(e)
|
|
157
|
+
backgrounds.append(None)
|
|
148
158
|
|
|
149
159
|
return backgrounds
|
|
150
160
|
|
|
@@ -266,28 +276,35 @@ def correct_background_model_free(
|
|
|
266
276
|
|
|
267
277
|
stack_path = get_position_movie_path(pos_path, prefix=movie_prefix)
|
|
268
278
|
print(f'Applying the correction to position {extract_position_name(pos_path)}...')
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
279
|
+
if stack_path is not None:
|
|
280
|
+
len_movie_auto = auto_load_number_of_frames(stack_path)
|
|
281
|
+
if len_movie_auto is not None:
|
|
282
|
+
len_movie = len_movie_auto
|
|
283
|
+
img_num_channels = _get_img_num_per_channel(channel_indices, int(len_movie), nbr_channels)
|
|
284
|
+
|
|
285
|
+
corrected_stack = apply_background_to_stack(stack_path,
|
|
286
|
+
background,
|
|
287
|
+
target_channel_index=channel_indices[0],
|
|
288
|
+
nbr_channels=nbr_channels,
|
|
289
|
+
stack_length=len_movie,
|
|
290
|
+
threshold_on_std=threshold_on_std,
|
|
291
|
+
optimize_option=optimize_option,
|
|
292
|
+
opt_coef_range=opt_coef_range,
|
|
293
|
+
opt_coef_nbr=opt_coef_nbr,
|
|
294
|
+
operation=operation,
|
|
295
|
+
clip=clip,
|
|
296
|
+
export=export,
|
|
297
|
+
activation_protocol=activation_protocol,
|
|
298
|
+
prefix=export_prefix,
|
|
299
|
+
)
|
|
300
|
+
print('Correction successful.')
|
|
301
|
+
if return_stacks:
|
|
302
|
+
stacks.append(corrected_stack)
|
|
303
|
+
else:
|
|
304
|
+
del corrected_stack
|
|
305
|
+
collect()
|
|
288
306
|
else:
|
|
289
|
-
|
|
290
|
-
collect()
|
|
307
|
+
stacks.append(None)
|
|
291
308
|
|
|
292
309
|
if return_stacks:
|
|
293
310
|
return stacks
|
|
@@ -770,7 +787,10 @@ def correct_background_model(
|
|
|
770
787
|
|
|
771
788
|
stack_path = get_position_movie_path(pos_path, prefix=movie_prefix)
|
|
772
789
|
print(f'Applying the correction to position {extract_position_name(pos_path)}...')
|
|
773
|
-
|
|
790
|
+
len_movie_auto = auto_load_number_of_frames(stack_path)
|
|
791
|
+
if len_movie_auto is not None:
|
|
792
|
+
len_movie = len_movie_auto
|
|
793
|
+
img_num_channels = _get_img_num_per_channel(channel_indices, int(len_movie), nbr_channels)
|
|
774
794
|
|
|
775
795
|
corrected_stack = fit_and_apply_model_background_to_stack(stack_path,
|
|
776
796
|
target_channel_index=channel_indices[0],
|