celldetective 1.4.2__py3-none-any.whl → 1.5.0b1__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 (152) 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 +403 -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/downloader.py +137 -0
  81. celldetective/processes/measure_cells.py +565 -0
  82. celldetective/processes/segment_cells.py +760 -0
  83. celldetective/processes/track_cells.py +435 -0
  84. celldetective/processes/train_segmentation_model.py +694 -0
  85. celldetective/processes/train_signal_model.py +265 -0
  86. celldetective/processes/unified_process.py +292 -0
  87. celldetective/regionprops/_regionprops.py +358 -317
  88. celldetective/relative_measurements.py +987 -710
  89. celldetective/scripts/measure_cells.py +313 -212
  90. celldetective/scripts/measure_relative.py +90 -46
  91. celldetective/scripts/segment_cells.py +165 -104
  92. celldetective/scripts/segment_cells_thresholds.py +96 -68
  93. celldetective/scripts/track_cells.py +198 -149
  94. celldetective/scripts/train_segmentation_model.py +324 -201
  95. celldetective/scripts/train_signal_model.py +87 -45
  96. celldetective/segmentation.py +844 -749
  97. celldetective/signals.py +3514 -2861
  98. celldetective/tracking.py +30 -15
  99. celldetective/utils/__init__.py +0 -0
  100. celldetective/utils/cellpose_utils/__init__.py +133 -0
  101. celldetective/utils/color_mappings.py +42 -0
  102. celldetective/utils/data_cleaning.py +630 -0
  103. celldetective/utils/data_loaders.py +450 -0
  104. celldetective/utils/dataset_helpers.py +207 -0
  105. celldetective/utils/downloaders.py +235 -0
  106. celldetective/utils/event_detection/__init__.py +8 -0
  107. celldetective/utils/experiment.py +1782 -0
  108. celldetective/utils/image_augmenters.py +308 -0
  109. celldetective/utils/image_cleaning.py +74 -0
  110. celldetective/utils/image_loaders.py +926 -0
  111. celldetective/utils/image_transforms.py +335 -0
  112. celldetective/utils/io.py +62 -0
  113. celldetective/utils/mask_cleaning.py +348 -0
  114. celldetective/utils/mask_transforms.py +5 -0
  115. celldetective/utils/masks.py +184 -0
  116. celldetective/utils/maths.py +351 -0
  117. celldetective/utils/model_getters.py +325 -0
  118. celldetective/utils/model_loaders.py +296 -0
  119. celldetective/utils/normalization.py +380 -0
  120. celldetective/utils/parsing.py +465 -0
  121. celldetective/utils/plots/__init__.py +0 -0
  122. celldetective/utils/plots/regression.py +53 -0
  123. celldetective/utils/resources.py +34 -0
  124. celldetective/utils/stardist_utils/__init__.py +104 -0
  125. celldetective/utils/stats.py +90 -0
  126. celldetective/utils/types.py +21 -0
  127. {celldetective-1.4.2.dist-info → celldetective-1.5.0b1.dist-info}/METADATA +1 -1
  128. celldetective-1.5.0b1.dist-info/RECORD +187 -0
  129. {celldetective-1.4.2.dist-info → celldetective-1.5.0b1.dist-info}/WHEEL +1 -1
  130. tests/gui/test_new_project.py +129 -117
  131. tests/gui/test_project.py +127 -79
  132. tests/test_filters.py +39 -15
  133. tests/test_notebooks.py +8 -0
  134. tests/test_tracking.py +232 -13
  135. tests/test_utils.py +123 -77
  136. celldetective/gui/base_components.py +0 -23
  137. celldetective/gui/layouts.py +0 -1602
  138. celldetective/gui/processes/compute_neighborhood.py +0 -594
  139. celldetective/gui/processes/downloader.py +0 -111
  140. celldetective/gui/processes/measure_cells.py +0 -360
  141. celldetective/gui/processes/segment_cells.py +0 -499
  142. celldetective/gui/processes/track_cells.py +0 -303
  143. celldetective/gui/processes/train_segmentation_model.py +0 -270
  144. celldetective/gui/processes/train_signal_model.py +0 -108
  145. celldetective/gui/table_ops/merge_groups.py +0 -118
  146. celldetective/gui/viewers.py +0 -1354
  147. celldetective/io.py +0 -3663
  148. celldetective/utils.py +0 -3108
  149. celldetective-1.4.2.dist-info/RECORD +0 -123
  150. {celldetective-1.4.2.dist-info → celldetective-1.5.0b1.dist-info}/entry_points.txt +0 -0
  151. {celldetective-1.4.2.dist-info → celldetective-1.5.0b1.dist-info}/licenses/LICENSE +0 -0
  152. {celldetective-1.4.2.dist-info → celldetective-1.5.0b1.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,14 @@
1
1
  import argparse
2
2
  import os
3
- from celldetective.relative_measurements import measure_pair_signals_at_position, extract_neighborhoods_from_pickles
4
- from celldetective.utils import config_section_to_dict, extract_experiment_channels
5
- from celldetective.io import get_experiment_populations
3
+ from celldetective.relative_measurements import (
4
+ measure_pair_signals_at_position,
5
+ extract_neighborhoods_from_pickles,
6
+ )
7
+ from celldetective.utils.experiment import (
8
+ extract_experiment_channels,
9
+ get_experiment_populations,
10
+ )
11
+ from celldetective.utils.parsing import config_section_to_dict
6
12
 
7
13
  from pathlib import Path, PurePath
8
14
 
@@ -13,21 +19,25 @@ from art import tprint
13
19
 
14
20
  tprint("Measure pairs")
15
21
 
16
- parser = argparse.ArgumentParser(description="Measure features and intensities in a multichannel timeseries.",
17
- formatter_class=argparse.ArgumentDefaultsHelpFormatter)
18
- parser.add_argument('-p', "--position", required=True, help="Path to the position")
22
+ parser = argparse.ArgumentParser(
23
+ description="Measure features and intensities in a multichannel timeseries.",
24
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
25
+ )
26
+ parser.add_argument("-p", "--position", required=True, help="Path to the position")
19
27
 
20
28
  args = parser.parse_args()
21
29
  process_arguments = vars(args)
22
- pos = str(process_arguments['position'])
30
+ pos = str(process_arguments["position"])
23
31
 
24
- instruction_file = os.sep.join(['configs', "neighborhood_instructions.json"])
32
+ instruction_file = os.sep.join(["configs", "neighborhood_instructions.json"])
25
33
 
26
34
  # Locate experiment config
27
35
  parent1 = Path(pos).parent
28
36
  expfolder = parent1.parent
29
37
  config = PurePath(expfolder, Path("config.ini"))
30
- assert os.path.exists(config), 'The configuration file for the experiment could not be located. Abort.'
38
+ assert os.path.exists(
39
+ config
40
+ ), "The configuration file for the experiment could not be located. Abort."
31
41
  print("Configuration file: ", config)
32
42
 
33
43
  # from exp config fetch spatial calib, channel names
@@ -42,51 +52,85 @@ populations = get_experiment_populations(expfolder, dtype=str)
42
52
 
43
53
  # from tracking instructions, fetch btrack config, features, haralick, clean_traj, idea: fetch custom timeline?
44
54
  instr_path = PurePath(expfolder, Path(f"{instruction_file}"))
45
- previous_pair_table_path = pos + os.sep.join(['output', 'tables', 'trajectories_pairs.csv'])
55
+ previous_pair_table_path = pos + os.sep.join(
56
+ ["output", "tables", "trajectories_pairs.csv"]
57
+ )
46
58
 
47
59
 
48
60
  previous_neighborhoods = []
49
61
  associated_reference_population = []
50
62
 
51
63
 
52
- neighborhoods_to_measure = extract_neighborhoods_from_pickles(pos, populations=populations)
64
+ neighborhoods_to_measure = extract_neighborhoods_from_pickles(
65
+ pos, populations=populations
66
+ )
53
67
  all_df_pairs = []
54
68
  if os.path.exists(previous_pair_table_path):
55
- df_0 = pd.read_csv(previous_pair_table_path)
56
- previous_neighborhoods = [c.replace('status_','') for c in list(df_0.columns) if c.startswith('status_neighborhood')]
57
- for n in previous_neighborhoods:
58
- associated_reference_population.append(df_0.loc[~df_0['status_'+n].isnull(),'reference_population'].values[0])
59
- print(f'{previous_neighborhoods=} {associated_reference_population=}')
60
- all_df_pairs.append(df_0)
61
- for k,neigh_protocol in enumerate(neighborhoods_to_measure):
62
- if neigh_protocol['description'] not in previous_neighborhoods:
63
- df_pairs = measure_pair_signals_at_position(pos, neigh_protocol)
64
- print(f'{df_pairs=}')
65
- if 'REFERENCE_ID' in list(df_pairs.columns):
66
- all_df_pairs.append(df_pairs)
67
- elif neigh_protocol['description'] in previous_neighborhoods and neigh_protocol['reference'] != associated_reference_population[previous_neighborhoods.index(neigh_protocol['description'])]:
68
- df_pairs = measure_pair_signals_at_position(pos, neigh_protocol)
69
- if 'REFERENCE_ID' in list(df_pairs.columns):
70
- all_df_pairs.append(df_pairs)
71
-
72
- print(f'{len(all_df_pairs)} neighborhood measurements sets were computed...')
73
-
74
- if len(all_df_pairs)>1:
75
- print('Merging...')
76
- df_pairs = all_df_pairs[0]
77
- for i in range(1,len(all_df_pairs)):
78
- cols = [c1 for c1,c2 in zip(list(df_pairs.columns), list(all_df_pairs[i].columns)) if c1==c2]
79
- df_pairs = pd.merge(df_pairs.round(decimals=6), all_df_pairs[i].round(decimals=6), how="outer", on=cols)
80
- elif len(all_df_pairs)==1:
81
- df_pairs = all_df_pairs[0]
69
+ df_0 = pd.read_csv(previous_pair_table_path)
70
+ previous_neighborhoods = [
71
+ c.replace("status_", "")
72
+ for c in list(df_0.columns)
73
+ if c.startswith("status_neighborhood")
74
+ ]
75
+ for n in previous_neighborhoods:
76
+ associated_reference_population.append(
77
+ df_0.loc[~df_0["status_" + n].isnull(), "reference_population"].values[0]
78
+ )
79
+ print(f"{previous_neighborhoods=} {associated_reference_population=}")
80
+ all_df_pairs.append(df_0)
81
+ for k, neigh_protocol in enumerate(neighborhoods_to_measure):
82
+ if neigh_protocol["description"] not in previous_neighborhoods:
83
+ df_pairs = measure_pair_signals_at_position(pos, neigh_protocol)
84
+ print(f"{df_pairs=}")
85
+ if "REFERENCE_ID" in list(df_pairs.columns):
86
+ all_df_pairs.append(df_pairs)
87
+ elif (
88
+ neigh_protocol["description"] in previous_neighborhoods
89
+ and neigh_protocol["reference"]
90
+ != associated_reference_population[
91
+ previous_neighborhoods.index(neigh_protocol["description"])
92
+ ]
93
+ ):
94
+ df_pairs = measure_pair_signals_at_position(pos, neigh_protocol)
95
+ if "REFERENCE_ID" in list(df_pairs.columns):
96
+ all_df_pairs.append(df_pairs)
97
+
98
+ print(f"{len(all_df_pairs)} neighborhood measurements sets were computed...")
99
+
100
+ if len(all_df_pairs) > 1:
101
+ print("Merging...")
102
+ df_pairs = all_df_pairs[0]
103
+ for i in range(1, len(all_df_pairs)):
104
+ cols = [
105
+ c1
106
+ for c1, c2 in zip(list(df_pairs.columns), list(all_df_pairs[i].columns))
107
+ if c1 == c2
108
+ ]
109
+ df_pairs = pd.merge(
110
+ df_pairs.round(decimals=6),
111
+ all_df_pairs[i].round(decimals=6),
112
+ how="outer",
113
+ on=cols,
114
+ )
115
+ elif len(all_df_pairs) == 1:
116
+ df_pairs = all_df_pairs[0]
82
117
  else:
83
- df_pairs = None
84
- print('No dataframe could be computed for the pairs...')
118
+ df_pairs = None
119
+ print("No dataframe could be computed for the pairs...")
85
120
 
86
121
  if df_pairs is not None:
87
- print('Writing table...')
88
- if "reference_population" in list(df_pairs.columns) and "neighbor_population" in list(df_pairs.columns):
89
- df_pairs = df_pairs.sort_values(by=['reference_population', 'neighbor_population', 'REFERENCE_ID', 'NEIGHBOR_ID', 'FRAME'])
90
- df_pairs.to_csv(previous_pair_table_path, index=False)
91
- print('Done.')
92
-
122
+ print("Writing table...")
123
+ if "reference_population" in list(
124
+ df_pairs.columns
125
+ ) and "neighbor_population" in list(df_pairs.columns):
126
+ df_pairs = df_pairs.sort_values(
127
+ by=[
128
+ "reference_population",
129
+ "neighbor_population",
130
+ "REFERENCE_ID",
131
+ "NEIGHBOR_ID",
132
+ "FRAME",
133
+ ]
134
+ )
135
+ df_pairs.to_csv(previous_pair_table_path, index=False)
136
+ print("Done.")
@@ -6,90 +6,129 @@ import argparse
6
6
  import datetime
7
7
  import os
8
8
  import json
9
- from celldetective.io import locate_segmentation_model, auto_load_number_of_frames, extract_position_name, _load_frames_to_segment, _check_label_dims
10
- from celldetective.utils import _prep_stardist_model, _prep_cellpose_model, _rescale_labels, _segment_image_with_stardist_model,_segment_image_with_cellpose_model,_get_normalize_kwargs_from_config, _estimate_scale_factor, _extract_channel_indices_from_config, config_section_to_dict, _extract_nbr_channels_from_config, _get_img_num_per_channel
9
+ from celldetective.utils.model_loaders import locate_segmentation_model
10
+ from celldetective.utils.image_loaders import (
11
+ auto_load_number_of_frames,
12
+ _load_frames_to_segment,
13
+ _get_img_num_per_channel,
14
+ )
15
+ from celldetective.utils.mask_cleaning import _check_label_dims
16
+ from celldetective.utils.experiment import extract_position_name
17
+ from celldetective.utils.stardist_utils import (
18
+ _prep_stardist_model,
19
+ _segment_image_with_stardist_model,
20
+ )
21
+ from celldetective.utils.cellpose_utils import (
22
+ _segment_image_with_cellpose_model,
23
+ _prep_cellpose_model,
24
+ )
25
+ from celldetective.utils.mask_transforms import _rescale_labels
26
+ from celldetective.utils.image_transforms import _estimate_scale_factor
27
+ from celldetective.utils.parsing import (
28
+ _get_normalize_kwargs_from_config,
29
+ config_section_to_dict,
30
+ _extract_channel_indices_from_config,
31
+ _extract_nbr_channels_from_config,
32
+ )
11
33
  from pathlib import Path, PurePath
12
34
  from glob import glob
13
35
  from shutil import rmtree
14
36
  from tqdm import tqdm
15
37
  import numpy as np
16
- from csbdeep.io import save_tiff_imagej_compatible
38
+ from celldetective.utils.io import save_tiff_imagej_compatible
17
39
  import gc
18
40
  from art import tprint
19
41
  import concurrent.futures
20
42
 
21
43
  tprint("Segment")
22
44
 
23
- parser = argparse.ArgumentParser(description="Segment a movie in position with the selected model",
24
- formatter_class=argparse.ArgumentDefaultsHelpFormatter)
25
- parser.add_argument('-p',"--position", required=True, help="Path to the position")
26
- parser.add_argument('-m',"--model", required=True,help="Model name")
27
- parser.add_argument("--mode", default="target", choices=["target","effector","targets","effectors"],help="Cell population of interest")
28
- parser.add_argument("--use_gpu", default="True", choices=["True","False"],help="use GPU")
29
- parser.add_argument("--threads", default="1",help="Number of parallel threads")
45
+ parser = argparse.ArgumentParser(
46
+ description="Segment a movie in position with the selected model",
47
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
48
+ )
49
+ parser.add_argument("-p", "--position", required=True, help="Path to the position")
50
+ parser.add_argument("-m", "--model", required=True, help="Model name")
51
+ parser.add_argument(
52
+ "--mode",
53
+ default="target",
54
+ choices=["target", "effector", "targets", "effectors"],
55
+ help="Cell population of interest",
56
+ )
57
+ parser.add_argument(
58
+ "--use_gpu", default="True", choices=["True", "False"], help="use GPU"
59
+ )
60
+ parser.add_argument("--threads", default="1", help="Number of parallel threads")
30
61
 
31
62
  args = parser.parse_args()
32
63
  process_arguments = vars(args)
33
- pos = str(process_arguments['position'])
34
- mode = str(process_arguments['mode'])
35
- use_gpu = process_arguments['use_gpu']
36
- n_threads = int(process_arguments['threads'])
37
-
38
- if use_gpu=='True' or use_gpu=='true' or use_gpu=='1':
39
- use_gpu = True
40
- n_threads = 1 # avoid misbehavior on GPU with multithreading
64
+ pos = str(process_arguments["position"])
65
+ mode = str(process_arguments["mode"])
66
+ use_gpu = process_arguments["use_gpu"]
67
+ n_threads = int(process_arguments["threads"])
68
+
69
+ if use_gpu == "True" or use_gpu == "true" or use_gpu == "1":
70
+ use_gpu = True
71
+ n_threads = 1 # avoid misbehavior on GPU with multithreading
41
72
  else:
42
- use_gpu = False
43
- #n_threads = 1 # force 1 threads since all CPUs seem to be in use anyway
73
+ use_gpu = False
74
+ # n_threads = 1 # force 1 threads since all CPUs seem to be in use anyway
44
75
 
45
76
  if not use_gpu:
46
- os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
77
+ os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
47
78
 
48
- modelname = str(process_arguments['model'])
79
+ modelname = str(process_arguments["model"])
49
80
 
50
- if mode.lower()=="target" or mode.lower()=="targets":
51
- label_folder = "labels_targets"
52
- elif mode.lower()=="effector" or mode.lower()=="effectors":
53
- label_folder = "labels_effectors"
81
+ if mode.lower() == "target" or mode.lower() == "targets":
82
+ label_folder = "labels_targets"
83
+ elif mode.lower() == "effector" or mode.lower() == "effectors":
84
+ label_folder = "labels_effectors"
54
85
 
55
86
  # Locate experiment config
56
87
  parent1 = Path(pos).parent
57
88
  expfolder = parent1.parent
58
- config = PurePath(expfolder,Path("config.ini"))
59
- assert os.path.exists(config),'The configuration file for the experiment could not be located. Abort.'
89
+ config = PurePath(expfolder, Path("config.ini"))
90
+ assert os.path.exists(
91
+ config
92
+ ), "The configuration file for the experiment could not be located. Abort."
60
93
 
61
94
  print(f"Position: {extract_position_name(pos)}...")
62
- print("Configuration file: ",config)
95
+ print("Configuration file: ", config)
63
96
  print(f"Population: {mode}...")
64
97
 
65
98
  ####################################
66
99
  # Check model requirements #########
67
100
  ####################################
68
101
 
69
- modelpath = os.sep.join([os.path.split(os.path.dirname(os.path.realpath(__file__)))[0],"models"])
102
+ modelpath = os.sep.join(
103
+ [os.path.split(os.path.dirname(os.path.realpath(__file__)))[0], "models"]
104
+ )
70
105
  model_complete_path = locate_segmentation_model(modelname)
71
106
  if model_complete_path is None:
72
- print('Model could not be found. Abort.')
73
- os.abort()
107
+ print("Model could not be found. Abort.")
108
+ os.abort()
74
109
  else:
75
- print(f'Model path: {model_complete_path}...')
110
+ print(f"Model path: {model_complete_path}...")
76
111
 
77
112
  # load config
78
- assert os.path.exists(model_complete_path+"config_input.json"),'The configuration for the inputs to the model could not be located. Abort.'
79
- with open(model_complete_path+"config_input.json") as config_file:
80
- input_config = json.load(config_file)
113
+ assert os.path.exists(
114
+ model_complete_path + "config_input.json"
115
+ ), "The configuration for the inputs to the model could not be located. Abort."
116
+ with open(model_complete_path + "config_input.json") as config_file:
117
+ input_config = json.load(config_file)
81
118
 
82
119
  # Parse target channels
83
120
  required_channels = input_config["channels"]
84
121
 
85
122
  channel_indices = _extract_channel_indices_from_config(config, required_channels)
86
- print(f'Required channels: {required_channels} located at channel indices {channel_indices}.')
87
- required_spatial_calibration = input_config['spatial_calibration']
88
- print(f'Spatial calibration expected by the model: {required_spatial_calibration}...')
123
+ print(
124
+ f"Required channels: {required_channels} located at channel indices {channel_indices}."
125
+ )
126
+ required_spatial_calibration = input_config["spatial_calibration"]
127
+ print(f"Spatial calibration expected by the model: {required_spatial_calibration}...")
89
128
 
90
129
  normalize_kwargs = _get_normalize_kwargs_from_config(input_config)
91
130
 
92
- model_type = input_config['model_type']
131
+ model_type = input_config["model_type"]
93
132
 
94
133
  movie_prefix = config_section_to_dict(config, "MovieSettings")["movie_prefix"]
95
134
  spatial_calibration = float(config_section_to_dict(config, "MovieSettings")["pxtoum"])
@@ -97,75 +136,102 @@ len_movie = float(config_section_to_dict(config, "MovieSettings")["len_movie"])
97
136
 
98
137
  # Try to find the file
99
138
  try:
100
- file = glob(pos+f"movie/{movie_prefix}*.tif")[0]
139
+ file = glob(pos + f"movie/{movie_prefix}*.tif")[0]
101
140
  except IndexError:
102
- print('Movie could not be found. Check the prefix.')
103
- os.abort()
141
+ print("Movie could not be found. Check the prefix.")
142
+ os.abort()
104
143
 
105
144
  len_movie_auto = auto_load_number_of_frames(file)
106
145
  if len_movie_auto is not None:
107
- len_movie = len_movie_auto
146
+ len_movie = len_movie_auto
108
147
 
109
- if model_type=='cellpose':
110
- diameter = input_config['diameter']
111
- # if diameter!=30:
112
- # required_spatial_calibration = None # ignore spatial calibration and use diameter
113
- cellprob_threshold = input_config['cellprob_threshold']
114
- flow_threshold = input_config['flow_threshold']
148
+ if model_type == "cellpose":
149
+ diameter = input_config["diameter"]
150
+ # if diameter!=30:
151
+ # required_spatial_calibration = None # ignore spatial calibration and use diameter
152
+ cellprob_threshold = input_config["cellprob_threshold"]
153
+ flow_threshold = input_config["flow_threshold"]
115
154
 
116
155
  scale = _estimate_scale_factor(spatial_calibration, required_spatial_calibration)
117
156
  print(f"Scale: {scale}...")
118
157
 
119
158
  nbr_channels = _extract_nbr_channels_from_config(config)
120
- #print(f'Number of channels in the input movie: {nbr_channels}')
121
- img_num_channels = _get_img_num_per_channel(channel_indices, int(len_movie), nbr_channels)
159
+ # print(f'Number of channels in the input movie: {nbr_channels}')
160
+ img_num_channels = _get_img_num_per_channel(
161
+ channel_indices, int(len_movie), nbr_channels
162
+ )
122
163
 
123
164
  # If everything OK, prepare output, load models
124
- if os.path.exists(pos+label_folder):
125
- print('Erasing the previous labels folder...')
126
- rmtree(pos+label_folder)
127
- os.mkdir(pos+label_folder)
128
- print(f'Labels folder successfully generated...')
165
+ if os.path.exists(pos + label_folder):
166
+ print("Erasing the previous labels folder...")
167
+ rmtree(pos + label_folder)
168
+ os.mkdir(pos + label_folder)
169
+ print(f"Labels folder successfully generated...")
129
170
 
130
- log=f'segmentation model: {modelname}\n'
131
- with open(pos+f'log_{mode}.json', 'a') as f:
132
- f.write(f'{datetime.datetime.now()} SEGMENT \n')
133
- f.write(log)
171
+ log = f"segmentation model: {modelname}\n"
172
+ with open(pos + f"log_{mode}.json", "a") as f:
173
+ f.write(f"{datetime.datetime.now()} SEGMENT \n")
174
+ f.write(log)
134
175
 
135
176
 
136
177
  # Loop over all frames and segment
137
178
  def segment_index(indices):
138
179
 
139
- if model_type=='stardist':
140
- model, scale_model = _prep_stardist_model(modelname, Path(model_complete_path).parent, use_gpu=use_gpu, scale=scale)
141
-
142
- elif model_type=='cellpose':
143
- model, scale_model = _prep_cellpose_model(modelname, model_complete_path, use_gpu=use_gpu, n_channels=len(required_channels), scale=scale)
144
-
145
- for t in tqdm(indices,desc="frame"):
146
-
147
- f = _load_frames_to_segment(file, img_num_channels[:,t], scale_model=scale_model, normalize_kwargs=normalize_kwargs)
148
-
149
- if model_type=="stardist":
150
- Y_pred = _segment_image_with_stardist_model(f, model=model, return_details=False)
151
- elif model_type=="cellpose":
152
- Y_pred = _segment_image_with_cellpose_model(f, model=model, diameter=diameter, cellprob_threshold=cellprob_threshold, flow_threshold=flow_threshold)
153
-
154
- if scale is not None:
155
- Y_pred = _rescale_labels(Y_pred, scale_model=scale_model)
156
-
157
- Y_pred = _check_label_dims(Y_pred, file)
158
-
159
- save_tiff_imagej_compatible(pos+os.sep.join([label_folder,f"{str(t).zfill(4)}.tif"]), Y_pred, axes='YX')
160
-
161
- del f;
162
- del Y_pred;
163
- gc.collect()
164
-
165
- del model;
166
- gc.collect()
167
-
168
- return
180
+ if model_type == "stardist":
181
+ model, scale_model = _prep_stardist_model(
182
+ modelname, Path(model_complete_path).parent, use_gpu=use_gpu, scale=scale
183
+ )
184
+
185
+ elif model_type == "cellpose":
186
+ model, scale_model = _prep_cellpose_model(
187
+ modelname,
188
+ model_complete_path,
189
+ use_gpu=use_gpu,
190
+ n_channels=len(required_channels),
191
+ scale=scale,
192
+ )
193
+
194
+ for t in tqdm(indices, desc="frame"):
195
+
196
+ f = _load_frames_to_segment(
197
+ file,
198
+ img_num_channels[:, t],
199
+ scale_model=scale_model,
200
+ normalize_kwargs=normalize_kwargs,
201
+ )
202
+
203
+ if model_type == "stardist":
204
+ Y_pred = _segment_image_with_stardist_model(
205
+ f, model=model, return_details=False
206
+ )
207
+ elif model_type == "cellpose":
208
+ Y_pred = _segment_image_with_cellpose_model(
209
+ f,
210
+ model=model,
211
+ diameter=diameter,
212
+ cellprob_threshold=cellprob_threshold,
213
+ flow_threshold=flow_threshold,
214
+ )
215
+
216
+ if scale is not None:
217
+ Y_pred = _rescale_labels(Y_pred, scale_model=scale_model)
218
+
219
+ Y_pred = _check_label_dims(Y_pred, file)
220
+
221
+ save_tiff_imagej_compatible(
222
+ pos + os.sep.join([label_folder, f"{str(t).zfill(4)}.tif"]),
223
+ Y_pred,
224
+ axes="YX",
225
+ )
226
+
227
+ del f
228
+ del Y_pred
229
+ gc.collect()
230
+
231
+ del model
232
+ gc.collect()
233
+
234
+ return
169
235
 
170
236
 
171
237
  print(f"Starting the segmentation with {n_threads} thread(s) and GPU={use_gpu}...")
@@ -175,17 +241,12 @@ indices = list(range(img_num_channels.shape[1]))
175
241
  chunks = np.array_split(indices, n_threads)
176
242
 
177
243
  with concurrent.futures.ThreadPoolExecutor() as executor:
178
- results = executor.map(segment_index, chunks)
179
- try:
180
- for i,return_value in enumerate(results):
181
- print(f"Thread {i} output check: ",return_value)
182
- except Exception as e:
183
- print("Exception: ", e)
184
-
185
- print('Done.')
244
+ results = executor.map(segment_index, chunks)
245
+ try:
246
+ for i, return_value in enumerate(results):
247
+ print(f"Thread {i} output check: ", return_value)
248
+ except Exception as e:
249
+ print("Exception: ", e)
250
+
251
+ print("Done.")
186
252
  gc.collect()
187
-
188
-
189
-
190
-
191
-