celldetective 1.4.2__py3-none-any.whl → 1.5.0b0__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 (151) hide show
  1. celldetective/__init__.py +25 -0
  2. celldetective/__main__.py +62 -43
  3. celldetective/_version.py +1 -1
  4. celldetective/extra_properties.py +477 -399
  5. celldetective/filters.py +192 -97
  6. celldetective/gui/InitWindow.py +541 -411
  7. celldetective/gui/__init__.py +0 -15
  8. celldetective/gui/about.py +44 -39
  9. celldetective/gui/analyze_block.py +120 -84
  10. celldetective/gui/base/__init__.py +0 -0
  11. celldetective/gui/base/channel_norm_generator.py +335 -0
  12. celldetective/gui/base/components.py +249 -0
  13. celldetective/gui/base/feature_choice.py +92 -0
  14. celldetective/gui/base/figure_canvas.py +52 -0
  15. celldetective/gui/base/list_widget.py +133 -0
  16. celldetective/gui/{styles.py → base/styles.py} +92 -36
  17. celldetective/gui/base/utils.py +33 -0
  18. celldetective/gui/base_annotator.py +900 -767
  19. celldetective/gui/classifier_widget.py +6 -22
  20. celldetective/gui/configure_new_exp.py +777 -671
  21. celldetective/gui/control_panel.py +635 -524
  22. celldetective/gui/dynamic_progress.py +449 -0
  23. celldetective/gui/event_annotator.py +2023 -1662
  24. celldetective/gui/generic_signal_plot.py +1292 -944
  25. celldetective/gui/gui_utils.py +899 -1289
  26. celldetective/gui/interactions_block.py +658 -0
  27. celldetective/gui/interactive_timeseries_viewer.py +447 -0
  28. celldetective/gui/json_readers.py +48 -15
  29. celldetective/gui/layouts/__init__.py +5 -0
  30. celldetective/gui/layouts/background_model_free_layout.py +537 -0
  31. celldetective/gui/layouts/channel_offset_layout.py +134 -0
  32. celldetective/gui/layouts/local_correction_layout.py +91 -0
  33. celldetective/gui/layouts/model_fit_layout.py +372 -0
  34. celldetective/gui/layouts/operation_layout.py +68 -0
  35. celldetective/gui/layouts/protocol_designer_layout.py +96 -0
  36. celldetective/gui/pair_event_annotator.py +3130 -2435
  37. celldetective/gui/plot_measurements.py +586 -267
  38. celldetective/gui/plot_signals_ui.py +724 -506
  39. celldetective/gui/preprocessing_block.py +395 -0
  40. celldetective/gui/process_block.py +1678 -1831
  41. celldetective/gui/seg_model_loader.py +580 -473
  42. celldetective/gui/settings/__init__.py +0 -7
  43. celldetective/gui/settings/_cellpose_model_params.py +181 -0
  44. celldetective/gui/settings/_event_detection_model_params.py +95 -0
  45. celldetective/gui/settings/_segmentation_model_params.py +159 -0
  46. celldetective/gui/settings/_settings_base.py +77 -65
  47. celldetective/gui/settings/_settings_event_model_training.py +752 -526
  48. celldetective/gui/settings/_settings_measurements.py +1133 -964
  49. celldetective/gui/settings/_settings_neighborhood.py +574 -488
  50. celldetective/gui/settings/_settings_segmentation_model_training.py +779 -564
  51. celldetective/gui/settings/_settings_signal_annotator.py +329 -305
  52. celldetective/gui/settings/_settings_tracking.py +1304 -1094
  53. celldetective/gui/settings/_stardist_model_params.py +98 -0
  54. celldetective/gui/survival_ui.py +422 -312
  55. celldetective/gui/tableUI.py +1665 -1701
  56. celldetective/gui/table_ops/_maths.py +295 -0
  57. celldetective/gui/table_ops/_merge_groups.py +140 -0
  58. celldetective/gui/table_ops/_merge_one_hot.py +95 -0
  59. celldetective/gui/table_ops/_query_table.py +43 -0
  60. celldetective/gui/table_ops/_rename_col.py +44 -0
  61. celldetective/gui/thresholds_gui.py +382 -179
  62. celldetective/gui/viewers/__init__.py +0 -0
  63. celldetective/gui/viewers/base_viewer.py +700 -0
  64. celldetective/gui/viewers/channel_offset_viewer.py +331 -0
  65. celldetective/gui/viewers/contour_viewer.py +394 -0
  66. celldetective/gui/viewers/size_viewer.py +153 -0
  67. celldetective/gui/viewers/spot_detection_viewer.py +341 -0
  68. celldetective/gui/viewers/threshold_viewer.py +309 -0
  69. celldetective/gui/workers.py +304 -126
  70. celldetective/log_manager.py +92 -0
  71. celldetective/measure.py +1895 -1478
  72. celldetective/napari/__init__.py +0 -0
  73. celldetective/napari/utils.py +1025 -0
  74. celldetective/neighborhood.py +1914 -1448
  75. celldetective/preprocessing.py +1620 -1220
  76. celldetective/processes/__init__.py +0 -0
  77. celldetective/processes/background_correction.py +271 -0
  78. celldetective/processes/compute_neighborhood.py +894 -0
  79. celldetective/processes/detect_events.py +246 -0
  80. celldetective/processes/measure_cells.py +565 -0
  81. celldetective/processes/segment_cells.py +760 -0
  82. celldetective/processes/track_cells.py +435 -0
  83. celldetective/processes/train_segmentation_model.py +694 -0
  84. celldetective/processes/train_signal_model.py +265 -0
  85. celldetective/processes/unified_process.py +292 -0
  86. celldetective/regionprops/_regionprops.py +358 -317
  87. celldetective/relative_measurements.py +987 -710
  88. celldetective/scripts/measure_cells.py +313 -212
  89. celldetective/scripts/measure_relative.py +90 -46
  90. celldetective/scripts/segment_cells.py +165 -104
  91. celldetective/scripts/segment_cells_thresholds.py +96 -68
  92. celldetective/scripts/track_cells.py +198 -149
  93. celldetective/scripts/train_segmentation_model.py +324 -201
  94. celldetective/scripts/train_signal_model.py +87 -45
  95. celldetective/segmentation.py +844 -749
  96. celldetective/signals.py +3514 -2861
  97. celldetective/tracking.py +30 -15
  98. celldetective/utils/__init__.py +0 -0
  99. celldetective/utils/cellpose_utils/__init__.py +133 -0
  100. celldetective/utils/color_mappings.py +42 -0
  101. celldetective/utils/data_cleaning.py +630 -0
  102. celldetective/utils/data_loaders.py +450 -0
  103. celldetective/utils/dataset_helpers.py +207 -0
  104. celldetective/utils/downloaders.py +197 -0
  105. celldetective/utils/event_detection/__init__.py +8 -0
  106. celldetective/utils/experiment.py +1782 -0
  107. celldetective/utils/image_augmenters.py +308 -0
  108. celldetective/utils/image_cleaning.py +74 -0
  109. celldetective/utils/image_loaders.py +926 -0
  110. celldetective/utils/image_transforms.py +335 -0
  111. celldetective/utils/io.py +62 -0
  112. celldetective/utils/mask_cleaning.py +348 -0
  113. celldetective/utils/mask_transforms.py +5 -0
  114. celldetective/utils/masks.py +184 -0
  115. celldetective/utils/maths.py +351 -0
  116. celldetective/utils/model_getters.py +325 -0
  117. celldetective/utils/model_loaders.py +296 -0
  118. celldetective/utils/normalization.py +380 -0
  119. celldetective/utils/parsing.py +465 -0
  120. celldetective/utils/plots/__init__.py +0 -0
  121. celldetective/utils/plots/regression.py +53 -0
  122. celldetective/utils/resources.py +34 -0
  123. celldetective/utils/stardist_utils/__init__.py +104 -0
  124. celldetective/utils/stats.py +90 -0
  125. celldetective/utils/types.py +21 -0
  126. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/METADATA +1 -1
  127. celldetective-1.5.0b0.dist-info/RECORD +187 -0
  128. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/WHEEL +1 -1
  129. tests/gui/test_new_project.py +129 -117
  130. tests/gui/test_project.py +127 -79
  131. tests/test_filters.py +39 -15
  132. tests/test_notebooks.py +8 -0
  133. tests/test_tracking.py +232 -13
  134. tests/test_utils.py +123 -77
  135. celldetective/gui/base_components.py +0 -23
  136. celldetective/gui/layouts.py +0 -1602
  137. celldetective/gui/processes/compute_neighborhood.py +0 -594
  138. celldetective/gui/processes/measure_cells.py +0 -360
  139. celldetective/gui/processes/segment_cells.py +0 -499
  140. celldetective/gui/processes/track_cells.py +0 -303
  141. celldetective/gui/processes/train_segmentation_model.py +0 -270
  142. celldetective/gui/processes/train_signal_model.py +0 -108
  143. celldetective/gui/table_ops/merge_groups.py +0 -118
  144. celldetective/gui/viewers.py +0 -1354
  145. celldetective/io.py +0 -3663
  146. celldetective/utils.py +0 -3108
  147. celldetective-1.4.2.dist-info/RECORD +0 -123
  148. /celldetective/{gui/processes → processes}/downloader.py +0 -0
  149. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/entry_points.txt +0 -0
  150. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/licenses/LICENSE +0 -0
  151. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/top_level.txt +0 -0
@@ -1,499 +0,0 @@
1
- from multiprocessing import Process
2
- import time
3
- import datetime
4
- import os
5
- import json
6
- import numpy as np
7
- from celldetective.io import (
8
- extract_position_name,
9
- locate_segmentation_model,
10
- auto_load_number_of_frames,
11
- load_frames,
12
- _check_label_dims,
13
- _load_frames_to_segment,
14
- )
15
- from celldetective.utils import (
16
- _rescale_labels,
17
- _segment_image_with_stardist_model,
18
- _segment_image_with_cellpose_model,
19
- _prep_stardist_model,
20
- _prep_cellpose_model,
21
- _get_normalize_kwargs_from_config,
22
- extract_experiment_channels,
23
- _estimate_scale_factor,
24
- _extract_channel_indices_from_config,
25
- config_section_to_dict,
26
- _extract_nbr_channels_from_config,
27
- _get_img_num_per_channel,
28
- )
29
-
30
- from pathlib import Path, PurePath
31
- from glob import glob
32
- from shutil import rmtree
33
- from tqdm import tqdm
34
- import numpy as np
35
- from csbdeep.io import save_tiff_imagej_compatible
36
- from celldetective.segmentation import (
37
- segment_frame_from_thresholds,
38
- merge_instance_segmentation,
39
- )
40
- import gc
41
- from art import tprint
42
-
43
- import concurrent.futures
44
-
45
-
46
- class BaseSegmentProcess(Process):
47
-
48
- def __init__(self, queue=None, process_args=None, *args, **kwargs):
49
-
50
- super().__init__(*args, **kwargs)
51
-
52
- self.queue = queue
53
-
54
- if process_args is not None:
55
- for key, value in process_args.items():
56
- setattr(self, key, value)
57
-
58
- tprint("Segment")
59
-
60
- # Experiment
61
- self.locate_experiment_config()
62
-
63
- print(f"Position: {extract_position_name(self.pos)}...")
64
- print("Configuration file: ", self.config)
65
- print(f"Population: {self.mode}...")
66
- self.instruction_file = os.sep.join(
67
- ["configs", f"segmentation_instructions_{self.mode}.json"]
68
- )
69
-
70
- self.read_instructions()
71
- self.extract_experiment_parameters()
72
- self.detect_movie_length()
73
- self.write_folders()
74
-
75
- def read_instructions(self):
76
- print("Looking for instruction file...")
77
- instr_path = PurePath(self.exp_dir, Path(f"{self.instruction_file}"))
78
- if os.path.exists(instr_path):
79
- with open(instr_path, "r") as f:
80
- _instructions = json.load(f)
81
- print(f"Measurement instruction file successfully loaded...")
82
- print(f"Instructions: {_instructions}...")
83
- self.flip = _instructions.get("flip", False)
84
- else:
85
- self.flip = False
86
-
87
- def write_folders(self):
88
-
89
- self.mode = self.mode.lower()
90
- self.label_folder = f"labels_{self.mode}"
91
-
92
- if os.path.exists(self.pos + self.label_folder):
93
- print("Erasing the previous labels folder...")
94
- rmtree(self.pos + self.label_folder)
95
- os.mkdir(self.pos + self.label_folder)
96
- print(f"Labels folder successfully generated...")
97
-
98
- def extract_experiment_parameters(self):
99
-
100
- self.spatial_calibration = float(
101
- config_section_to_dict(self.config, "MovieSettings")["pxtoum"]
102
- )
103
- self.len_movie = float(
104
- config_section_to_dict(self.config, "MovieSettings")["len_movie"]
105
- )
106
- self.movie_prefix = config_section_to_dict(self.config, "MovieSettings")[
107
- "movie_prefix"
108
- ]
109
- self.nbr_channels = _extract_nbr_channels_from_config(self.config)
110
- self.channel_names, self.channel_indices = extract_experiment_channels(
111
- self.exp_dir
112
- )
113
-
114
- def locate_experiment_config(self):
115
-
116
- parent1 = Path(self.pos).parent
117
- self.exp_dir = parent1.parent
118
- self.config = PurePath(self.exp_dir, Path("config.ini"))
119
-
120
- if not os.path.exists(self.config):
121
- print(
122
- "The configuration file for the experiment could not be located. Abort."
123
- )
124
- self.abort_process()
125
-
126
- def detect_movie_length(self):
127
-
128
- try:
129
- self.file = glob(self.pos + f"movie/{self.movie_prefix}*.tif")[0]
130
- except Exception as e:
131
- print(f"Error {e}.\nMovie could not be found. Check the prefix.")
132
- self.abort_process()
133
-
134
- len_movie_auto = auto_load_number_of_frames(self.file)
135
- if len_movie_auto is not None:
136
- self.len_movie = len_movie_auto
137
-
138
- def end_process(self):
139
-
140
- self.terminate()
141
- self.queue.put("finished")
142
-
143
- def abort_process(self):
144
-
145
- self.terminate()
146
- self.queue.put("error")
147
-
148
-
149
- class SegmentCellDLProcess(BaseSegmentProcess):
150
-
151
- def __init__(self, *args, **kwargs):
152
-
153
- super().__init__(*args, **kwargs)
154
-
155
- self.check_gpu()
156
-
157
- # Model
158
- self.locate_model_path()
159
- self.extract_model_input_parameters()
160
- self.detect_channels()
161
- self.detect_rescaling()
162
-
163
- self.write_log()
164
-
165
- self.sum_done = 0
166
- self.t0 = time.time()
167
-
168
- def extract_model_input_parameters(self):
169
-
170
- self.required_channels = self.input_config["channels"]
171
- if "selected_channels" in self.input_config:
172
- self.required_channels = self.input_config["selected_channels"]
173
-
174
- self.target_cell_size = None
175
- if (
176
- "target_cell_size_um" in self.input_config
177
- and "cell_size_um" in self.input_config
178
- ):
179
- self.target_cell_size = self.input_config["target_cell_size_um"]
180
- self.cell_size = self.input_config["cell_size_um"]
181
-
182
- self.normalize_kwargs = _get_normalize_kwargs_from_config(self.input_config)
183
-
184
- self.model_type = self.input_config["model_type"]
185
- self.required_spatial_calibration = self.input_config["spatial_calibration"]
186
- print(
187
- f"Spatial calibration expected by the model: {self.required_spatial_calibration}..."
188
- )
189
-
190
- if self.model_type == "cellpose":
191
- self.diameter = self.input_config["diameter"]
192
- self.cellprob_threshold = self.input_config["cellprob_threshold"]
193
- self.flow_threshold = self.input_config["flow_threshold"]
194
-
195
- def write_log(self):
196
-
197
- log = f"segmentation model: {self.model_name}\n"
198
- with open(self.pos + f"log_{self.mode}.txt", "a") as f:
199
- f.write(f"{datetime.datetime.now()} SEGMENT \n")
200
- f.write(log)
201
-
202
- def detect_channels(self):
203
-
204
- self.channel_indices = _extract_channel_indices_from_config(
205
- self.config, self.required_channels
206
- )
207
- print(
208
- f"Required channels: {self.required_channels} located at channel indices {self.channel_indices}."
209
- )
210
- self.img_num_channels = _get_img_num_per_channel(
211
- self.channel_indices, int(self.len_movie), self.nbr_channels
212
- )
213
-
214
- def detect_rescaling(self):
215
-
216
- self.scale = _estimate_scale_factor(
217
- self.spatial_calibration, self.required_spatial_calibration
218
- )
219
- print(f"Scale: {self.scale}...")
220
-
221
- if self.target_cell_size is not None and self.scale is not None:
222
- self.scale *= self.cell_size / self.target_cell_size
223
- elif self.target_cell_size is not None:
224
- if self.target_cell_size != self.cell_size:
225
- self.scale = self.cell_size / self.target_cell_size
226
-
227
- print(f"Scale accounting for expected cell size: {self.scale}...")
228
-
229
- def locate_model_path(self):
230
-
231
- self.model_complete_path = locate_segmentation_model(self.model_name)
232
- if self.model_complete_path is None:
233
- print("Model could not be found. Abort.")
234
- self.abort_process()
235
- else:
236
- print(f"Model path: {self.model_complete_path}...")
237
-
238
- if not os.path.exists(self.model_complete_path + "config_input.json"):
239
- print(
240
- "The configuration for the inputs to the model could not be located. Abort."
241
- )
242
- self.abort_process()
243
-
244
- with open(self.model_complete_path + "config_input.json") as config_file:
245
- self.input_config = json.load(config_file)
246
-
247
- def check_gpu(self):
248
-
249
- if not self.use_gpu:
250
- os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
251
-
252
- def run(self):
253
-
254
- try:
255
-
256
- if self.model_type == "stardist":
257
- model, scale_model = _prep_stardist_model(
258
- self.model_name,
259
- Path(self.model_complete_path).parent,
260
- use_gpu=self.use_gpu,
261
- scale=self.scale,
262
- )
263
-
264
- elif self.model_type == "cellpose":
265
- model, scale_model = _prep_cellpose_model(
266
- self.model_name,
267
- self.model_complete_path,
268
- use_gpu=self.use_gpu,
269
- n_channels=len(self.required_channels),
270
- scale=self.scale,
271
- )
272
-
273
- list_indices = range(self.len_movie)
274
- if self.flip:
275
- list_indices = reversed(list_indices)
276
-
277
- for i, t in enumerate(tqdm(list_indices, desc="frame")):
278
-
279
- f = _load_frames_to_segment(
280
- self.file,
281
- self.img_num_channels[:, t],
282
- scale_model=scale_model,
283
- normalize_kwargs=self.normalize_kwargs,
284
- )
285
-
286
- if self.model_type == "stardist":
287
- Y_pred = _segment_image_with_stardist_model(
288
- f, model=model, return_details=False
289
- )
290
-
291
- elif self.model_type == "cellpose":
292
- Y_pred = _segment_image_with_cellpose_model(
293
- f,
294
- model=model,
295
- diameter=self.diameter,
296
- cellprob_threshold=self.cellprob_threshold,
297
- flow_threshold=self.flow_threshold,
298
- )
299
-
300
- if self.scale is not None:
301
- Y_pred = _rescale_labels(Y_pred, scale_model=scale_model)
302
-
303
- Y_pred = _check_label_dims(Y_pred, file=self.file)
304
-
305
- save_tiff_imagej_compatible(
306
- self.pos
307
- + os.sep.join([self.label_folder, f"{str(t).zfill(4)}.tif"]),
308
- Y_pred,
309
- axes="YX",
310
- )
311
-
312
- del f
313
- del Y_pred
314
- gc.collect()
315
-
316
- # Send signal for progress bar
317
- self.sum_done += 1 / self.len_movie * 100
318
- mean_exec_per_step = (time.time() - self.t0) / (i + 1)
319
- pred_time = (self.len_movie - (i + 1)) * mean_exec_per_step
320
- self.queue.put([self.sum_done, pred_time])
321
-
322
- except Exception as e:
323
- print(e)
324
-
325
- try:
326
- del model
327
- except:
328
- pass
329
-
330
- gc.collect()
331
- print("Done.")
332
-
333
- # Send end signal
334
- self.queue.put("finished")
335
- self.queue.close()
336
-
337
-
338
- class SegmentCellThresholdProcess(BaseSegmentProcess):
339
-
340
- def __init__(self, *args, **kwargs):
341
-
342
- super().__init__(*args, **kwargs)
343
-
344
- self.equalize = False
345
-
346
- # Model
347
-
348
- self.load_threshold_config()
349
- self.extract_threshold_parameters()
350
- self.detect_channels()
351
- self.prepare_equalize()
352
-
353
- self.write_log()
354
-
355
- self.sum_done = 0
356
- self.t0 = time.time()
357
-
358
- def prepare_equalize(self):
359
-
360
- for i in range(len(self.instructions)):
361
-
362
- if self.equalize[i]:
363
- f_reference = load_frames(
364
- self.img_num_channels[:, self.equalize_time[i]],
365
- self.file,
366
- scale=None,
367
- normalize_input=False,
368
- )
369
- f_reference = f_reference[:, :, self.instructions[i]["target_channel"]]
370
- else:
371
- f_reference = None
372
-
373
- self.instructions[i].update({"equalize_reference": f_reference})
374
-
375
- def load_threshold_config(self):
376
-
377
- self.instructions = []
378
- for inst in self.threshold_instructions:
379
- if os.path.exists(inst):
380
- with open(inst, "r") as f:
381
- self.instructions.append(json.load(f))
382
- else:
383
- print("The configuration path is not valid. Abort.")
384
- self.abort_process()
385
-
386
- def extract_threshold_parameters(self):
387
-
388
- self.required_channels = []
389
- self.equalize = []
390
- self.equalize_time = []
391
-
392
- for i in range(len(self.instructions)):
393
- ch = [self.instructions[i]["target_channel"]]
394
- self.required_channels.append(ch)
395
-
396
- if "equalize_reference" in self.instructions[i]:
397
- equalize, equalize_time = self.instructions[i]["equalize_reference"]
398
- self.equalize.append(equalize)
399
- self.equalize_time.append(equalize_time)
400
-
401
- def write_log(self):
402
-
403
- log = f"Threshold segmentation: {self.threshold_instructions}\n"
404
- with open(self.pos + f"log_{self.mode}.txt", "a") as f:
405
- f.write(f"{datetime.datetime.now()} SEGMENT \n")
406
- f.write(log)
407
-
408
- def detect_channels(self):
409
-
410
- for i in range(len(self.instructions)):
411
-
412
- self.channel_indices = _extract_channel_indices_from_config(
413
- self.config, self.required_channels[i]
414
- )
415
- print(
416
- f"Required channels: {self.required_channels[i]} located at channel indices {self.channel_indices}."
417
- )
418
- self.instructions[i].update({"target_channel": self.channel_indices[0]})
419
- self.instructions[i].update({"channel_names": self.channel_names})
420
-
421
- self.img_num_channels = _get_img_num_per_channel(
422
- np.arange(self.nbr_channels), self.len_movie, self.nbr_channels
423
- )
424
-
425
- def parallel_job(self, indices):
426
-
427
- try:
428
-
429
- for t in tqdm(
430
- indices, desc="frame"
431
- ): # for t in tqdm(range(self.len_movie),desc="frame"):
432
-
433
- # Load channels at time t
434
- masks = []
435
- for i in range(len(self.instructions)):
436
- f = load_frames(
437
- self.img_num_channels[:, t],
438
- self.file,
439
- scale=None,
440
- normalize_input=False,
441
- )
442
- mask = segment_frame_from_thresholds(f, **self.instructions[i])
443
- # print(f'Frame {t}; segment with {self.instructions[i]=}...')
444
- masks.append(mask)
445
-
446
- if len(self.instructions) > 1:
447
- mask = merge_instance_segmentation(masks, mode="OR")
448
-
449
- save_tiff_imagej_compatible(
450
- os.sep.join(
451
- [self.pos, self.label_folder, f"{str(t).zfill(4)}.tif"]
452
- ),
453
- mask.astype(np.uint16),
454
- axes="YX",
455
- )
456
-
457
- del f
458
- del mask
459
- gc.collect()
460
-
461
- # Send signal for progress bar
462
- self.sum_done += 1 / self.len_movie * 100
463
- mean_exec_per_step = (time.time() - self.t0) / (
464
- self.sum_done * self.len_movie / 100 + 1
465
- )
466
- pred_time = (
467
- self.len_movie - (self.sum_done * self.len_movie / 100 + 1)
468
- ) * mean_exec_per_step
469
- self.queue.put([self.sum_done, pred_time])
470
-
471
- except Exception as e:
472
- print(e)
473
-
474
- return
475
-
476
- def run(self):
477
-
478
- self.indices = list(range(self.img_num_channels.shape[1]))
479
- if self.flip:
480
- self.indices = np.array(list(reversed(self.indices)))
481
-
482
- chunks = np.array_split(self.indices, self.n_threads)
483
-
484
- with concurrent.futures.ThreadPoolExecutor(
485
- max_workers=self.n_threads
486
- ) as executor:
487
- results = results = executor.map(
488
- self.parallel_job, chunks
489
- ) # list(map(lambda x: executor.submit(self.parallel_job, x), chunks))
490
- try:
491
- for i, return_value in enumerate(results):
492
- print(f"Thread {i} output check: ", return_value)
493
- except Exception as e:
494
- print("Exception: ", e)
495
-
496
- print("Done.")
497
- # Send end signal
498
- self.queue.put("finished")
499
- self.queue.close()