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.
Files changed (42) hide show
  1. celldetective/__init__.py +2 -1
  2. celldetective/__main__.py +17 -0
  3. celldetective/extra_properties.py +62 -34
  4. celldetective/gui/__init__.py +1 -0
  5. celldetective/gui/analyze_block.py +2 -1
  6. celldetective/gui/classifier_widget.py +18 -10
  7. celldetective/gui/control_panel.py +57 -6
  8. celldetective/gui/layouts.py +14 -11
  9. celldetective/gui/neighborhood_options.py +21 -13
  10. celldetective/gui/plot_signals_ui.py +39 -11
  11. celldetective/gui/process_block.py +413 -95
  12. celldetective/gui/retrain_segmentation_model_options.py +17 -4
  13. celldetective/gui/retrain_signal_model_options.py +106 -6
  14. celldetective/gui/signal_annotator.py +110 -30
  15. celldetective/gui/signal_annotator2.py +2708 -0
  16. celldetective/gui/signal_annotator_options.py +3 -1
  17. celldetective/gui/survival_ui.py +15 -6
  18. celldetective/gui/tableUI.py +248 -43
  19. celldetective/io.py +598 -416
  20. celldetective/measure.py +919 -969
  21. celldetective/models/pair_signal_detection/blank +0 -0
  22. celldetective/neighborhood.py +482 -340
  23. celldetective/preprocessing.py +81 -61
  24. celldetective/relative_measurements.py +648 -0
  25. celldetective/scripts/analyze_signals.py +1 -1
  26. celldetective/scripts/measure_cells.py +28 -8
  27. celldetective/scripts/measure_relative.py +103 -0
  28. celldetective/scripts/segment_cells.py +5 -5
  29. celldetective/scripts/track_cells.py +4 -1
  30. celldetective/scripts/train_segmentation_model.py +23 -18
  31. celldetective/scripts/train_signal_model.py +33 -0
  32. celldetective/segmentation.py +67 -29
  33. celldetective/signals.py +402 -8
  34. celldetective/tracking.py +8 -2
  35. celldetective/utils.py +144 -12
  36. {celldetective-1.1.1.post3.dist-info → celldetective-1.2.0.dist-info}/METADATA +8 -8
  37. {celldetective-1.1.1.post3.dist-info → celldetective-1.2.0.dist-info}/RECORD +42 -38
  38. {celldetective-1.1.1.post3.dist-info → celldetective-1.2.0.dist-info}/WHEEL +1 -1
  39. tests/test_segmentation.py +1 -1
  40. {celldetective-1.1.1.post3.dist-info → celldetective-1.2.0.dist-info}/LICENSE +0 -0
  41. {celldetective-1.1.1.post3.dist-info → celldetective-1.2.0.dist-info}/entry_points.txt +0 -0
  42. {celldetective-1.1.1.post3.dist-info → celldetective-1.2.0.dist-info}/top_level.txt +0 -0
@@ -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
- if mode=="timeseries":
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
- frames = load_frames(img_num_channels[0,:], stack_path, normalize_input=False).astype(float)
122
- frames = np.moveaxis(frames, -1, 0).astype(float)
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
- new_frames = []
125
- for i in range(len(frames)):
110
+ for i in range(len(frames)):
111
+ if np.all(frames[i].flatten()==0):
112
+ frames[i,:,:] = np.nan
126
113
 
127
- if np.all(frames[i].flatten()==0):
128
- empty_frame = np.zeros_like(frames[i])
129
- empty_frame[:,:] = np.nan
130
- new_frames.append(empty_frame)
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
- f[np.where(mask.astype(int)==1)] = np.nan
138
- new_frames.append(f.copy())
139
-
140
- frame = np.nanmedian(new_frames, axis=0)
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
- background = np.nanmedian(frame_mean_per_position,axis=0)
146
- backgrounds.append({"bg": background, "well": well_path})
147
- print(f"Background successfully computed for well {well_name}...")
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
- corrected_stack = apply_background_to_stack(stack_path,
271
- background,
272
- target_channel_index=channel_indices[0],
273
- nbr_channels=nbr_channels,
274
- stack_length=len_movie,
275
- threshold_on_std=threshold_on_std,
276
- optimize_option=optimize_option,
277
- opt_coef_range=opt_coef_range,
278
- opt_coef_nbr=opt_coef_nbr,
279
- operation=operation,
280
- clip=clip,
281
- export=export,
282
- activation_protocol=activation_protocol,
283
- prefix=export_prefix,
284
- )
285
- print('Correction successful.')
286
- if return_stacks:
287
- stacks.append(corrected_stack)
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
- del corrected_stack
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
- print(stack_path)
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],