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.
- celldetective/__init__.py +25 -0
- celldetective/__main__.py +62 -43
- celldetective/_version.py +1 -1
- celldetective/extra_properties.py +477 -399
- celldetective/filters.py +192 -97
- celldetective/gui/InitWindow.py +541 -411
- celldetective/gui/__init__.py +0 -15
- celldetective/gui/about.py +44 -39
- celldetective/gui/analyze_block.py +120 -84
- celldetective/gui/base/__init__.py +0 -0
- celldetective/gui/base/channel_norm_generator.py +335 -0
- celldetective/gui/base/components.py +249 -0
- celldetective/gui/base/feature_choice.py +92 -0
- celldetective/gui/base/figure_canvas.py +52 -0
- celldetective/gui/base/list_widget.py +133 -0
- celldetective/gui/{styles.py → base/styles.py} +92 -36
- celldetective/gui/base/utils.py +33 -0
- celldetective/gui/base_annotator.py +900 -767
- celldetective/gui/classifier_widget.py +6 -22
- celldetective/gui/configure_new_exp.py +777 -671
- celldetective/gui/control_panel.py +635 -524
- celldetective/gui/dynamic_progress.py +449 -0
- celldetective/gui/event_annotator.py +2023 -1662
- celldetective/gui/generic_signal_plot.py +1292 -944
- celldetective/gui/gui_utils.py +899 -1289
- celldetective/gui/interactions_block.py +658 -0
- celldetective/gui/interactive_timeseries_viewer.py +447 -0
- celldetective/gui/json_readers.py +48 -15
- celldetective/gui/layouts/__init__.py +5 -0
- celldetective/gui/layouts/background_model_free_layout.py +537 -0
- celldetective/gui/layouts/channel_offset_layout.py +134 -0
- celldetective/gui/layouts/local_correction_layout.py +91 -0
- celldetective/gui/layouts/model_fit_layout.py +372 -0
- celldetective/gui/layouts/operation_layout.py +68 -0
- celldetective/gui/layouts/protocol_designer_layout.py +96 -0
- celldetective/gui/pair_event_annotator.py +3130 -2435
- celldetective/gui/plot_measurements.py +586 -267
- celldetective/gui/plot_signals_ui.py +724 -506
- celldetective/gui/preprocessing_block.py +395 -0
- celldetective/gui/process_block.py +1678 -1831
- celldetective/gui/seg_model_loader.py +580 -473
- celldetective/gui/settings/__init__.py +0 -7
- celldetective/gui/settings/_cellpose_model_params.py +181 -0
- celldetective/gui/settings/_event_detection_model_params.py +95 -0
- celldetective/gui/settings/_segmentation_model_params.py +159 -0
- celldetective/gui/settings/_settings_base.py +77 -65
- celldetective/gui/settings/_settings_event_model_training.py +752 -526
- celldetective/gui/settings/_settings_measurements.py +1133 -964
- celldetective/gui/settings/_settings_neighborhood.py +574 -488
- celldetective/gui/settings/_settings_segmentation_model_training.py +779 -564
- celldetective/gui/settings/_settings_signal_annotator.py +329 -305
- celldetective/gui/settings/_settings_tracking.py +1304 -1094
- celldetective/gui/settings/_stardist_model_params.py +98 -0
- celldetective/gui/survival_ui.py +422 -312
- celldetective/gui/tableUI.py +1665 -1701
- celldetective/gui/table_ops/_maths.py +295 -0
- celldetective/gui/table_ops/_merge_groups.py +140 -0
- celldetective/gui/table_ops/_merge_one_hot.py +95 -0
- celldetective/gui/table_ops/_query_table.py +43 -0
- celldetective/gui/table_ops/_rename_col.py +44 -0
- celldetective/gui/thresholds_gui.py +382 -179
- celldetective/gui/viewers/__init__.py +0 -0
- celldetective/gui/viewers/base_viewer.py +700 -0
- celldetective/gui/viewers/channel_offset_viewer.py +331 -0
- celldetective/gui/viewers/contour_viewer.py +394 -0
- celldetective/gui/viewers/size_viewer.py +153 -0
- celldetective/gui/viewers/spot_detection_viewer.py +341 -0
- celldetective/gui/viewers/threshold_viewer.py +309 -0
- celldetective/gui/workers.py +304 -126
- celldetective/log_manager.py +92 -0
- celldetective/measure.py +1895 -1478
- celldetective/napari/__init__.py +0 -0
- celldetective/napari/utils.py +1025 -0
- celldetective/neighborhood.py +1914 -1448
- celldetective/preprocessing.py +1620 -1220
- celldetective/processes/__init__.py +0 -0
- celldetective/processes/background_correction.py +271 -0
- celldetective/processes/compute_neighborhood.py +894 -0
- celldetective/processes/detect_events.py +246 -0
- celldetective/processes/measure_cells.py +565 -0
- celldetective/processes/segment_cells.py +760 -0
- celldetective/processes/track_cells.py +435 -0
- celldetective/processes/train_segmentation_model.py +694 -0
- celldetective/processes/train_signal_model.py +265 -0
- celldetective/processes/unified_process.py +292 -0
- celldetective/regionprops/_regionprops.py +358 -317
- celldetective/relative_measurements.py +987 -710
- celldetective/scripts/measure_cells.py +313 -212
- celldetective/scripts/measure_relative.py +90 -46
- celldetective/scripts/segment_cells.py +165 -104
- celldetective/scripts/segment_cells_thresholds.py +96 -68
- celldetective/scripts/track_cells.py +198 -149
- celldetective/scripts/train_segmentation_model.py +324 -201
- celldetective/scripts/train_signal_model.py +87 -45
- celldetective/segmentation.py +844 -749
- celldetective/signals.py +3514 -2861
- celldetective/tracking.py +30 -15
- celldetective/utils/__init__.py +0 -0
- celldetective/utils/cellpose_utils/__init__.py +133 -0
- celldetective/utils/color_mappings.py +42 -0
- celldetective/utils/data_cleaning.py +630 -0
- celldetective/utils/data_loaders.py +450 -0
- celldetective/utils/dataset_helpers.py +207 -0
- celldetective/utils/downloaders.py +197 -0
- celldetective/utils/event_detection/__init__.py +8 -0
- celldetective/utils/experiment.py +1782 -0
- celldetective/utils/image_augmenters.py +308 -0
- celldetective/utils/image_cleaning.py +74 -0
- celldetective/utils/image_loaders.py +926 -0
- celldetective/utils/image_transforms.py +335 -0
- celldetective/utils/io.py +62 -0
- celldetective/utils/mask_cleaning.py +348 -0
- celldetective/utils/mask_transforms.py +5 -0
- celldetective/utils/masks.py +184 -0
- celldetective/utils/maths.py +351 -0
- celldetective/utils/model_getters.py +325 -0
- celldetective/utils/model_loaders.py +296 -0
- celldetective/utils/normalization.py +380 -0
- celldetective/utils/parsing.py +465 -0
- celldetective/utils/plots/__init__.py +0 -0
- celldetective/utils/plots/regression.py +53 -0
- celldetective/utils/resources.py +34 -0
- celldetective/utils/stardist_utils/__init__.py +104 -0
- celldetective/utils/stats.py +90 -0
- celldetective/utils/types.py +21 -0
- {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/METADATA +1 -1
- celldetective-1.5.0b0.dist-info/RECORD +187 -0
- {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/WHEEL +1 -1
- tests/gui/test_new_project.py +129 -117
- tests/gui/test_project.py +127 -79
- tests/test_filters.py +39 -15
- tests/test_notebooks.py +8 -0
- tests/test_tracking.py +232 -13
- tests/test_utils.py +123 -77
- celldetective/gui/base_components.py +0 -23
- celldetective/gui/layouts.py +0 -1602
- celldetective/gui/processes/compute_neighborhood.py +0 -594
- celldetective/gui/processes/measure_cells.py +0 -360
- celldetective/gui/processes/segment_cells.py +0 -499
- celldetective/gui/processes/track_cells.py +0 -303
- celldetective/gui/processes/train_segmentation_model.py +0 -270
- celldetective/gui/processes/train_signal_model.py +0 -108
- celldetective/gui/table_ops/merge_groups.py +0 -118
- celldetective/gui/viewers.py +0 -1354
- celldetective/io.py +0 -3663
- celldetective/utils.py +0 -3108
- celldetective-1.4.2.dist-info/RECORD +0 -123
- /celldetective/{gui/processes → processes}/downloader.py +0 -0
- {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/entry_points.txt +0 -0
- {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/licenses/LICENSE +0 -0
- {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/top_level.txt +0 -0
|
@@ -6,10 +6,22 @@ import argparse
|
|
|
6
6
|
import datetime
|
|
7
7
|
import os
|
|
8
8
|
import json
|
|
9
|
-
from celldetective.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
from celldetective.utils.data_loaders import interpret_tracking_configuration
|
|
10
|
+
from celldetective.utils.image_loaders import (
|
|
11
|
+
locate_labels,
|
|
12
|
+
auto_load_number_of_frames,
|
|
13
|
+
_load_frames_to_measure,
|
|
14
|
+
_get_img_num_per_channel,
|
|
15
|
+
)
|
|
16
|
+
from celldetective.utils.experiment import (
|
|
17
|
+
extract_position_name,
|
|
18
|
+
extract_experiment_channels,
|
|
19
|
+
)
|
|
20
|
+
from celldetective import (
|
|
21
|
+
extract_experiment_channels,
|
|
22
|
+
)
|
|
23
|
+
from celldetective.utils.data_cleaning import _mask_intensity_measurements
|
|
24
|
+
from celldetective.utils.parsing import config_section_to_dict
|
|
13
25
|
from celldetective.measure import drop_tonal_features, measure_features
|
|
14
26
|
from celldetective.tracking import track
|
|
15
27
|
from pathlib import Path, PurePath
|
|
@@ -26,44 +38,53 @@ import concurrent.futures
|
|
|
26
38
|
|
|
27
39
|
tprint("Track")
|
|
28
40
|
|
|
29
|
-
parser = argparse.ArgumentParser(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
parser.add_argument("
|
|
41
|
+
parser = argparse.ArgumentParser(
|
|
42
|
+
description="Segment a movie in position with the selected model",
|
|
43
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
44
|
+
)
|
|
45
|
+
parser.add_argument("-p", "--position", required=True, help="Path to the position")
|
|
46
|
+
parser.add_argument(
|
|
47
|
+
"--mode",
|
|
48
|
+
default="target",
|
|
49
|
+
choices=["target", "effector", "targets", "effectors"],
|
|
50
|
+
help="Cell population of interest",
|
|
51
|
+
)
|
|
52
|
+
parser.add_argument("--threads", default="1", help="Number of parallel threads")
|
|
34
53
|
|
|
35
54
|
args = parser.parse_args()
|
|
36
55
|
process_arguments = vars(args)
|
|
37
|
-
pos = str(process_arguments[
|
|
38
|
-
mode = str(process_arguments[
|
|
39
|
-
n_threads = int(process_arguments[
|
|
56
|
+
pos = str(process_arguments["position"])
|
|
57
|
+
mode = str(process_arguments["mode"])
|
|
58
|
+
n_threads = int(process_arguments["threads"])
|
|
40
59
|
|
|
41
|
-
if not os.path.exists(pos+"output"):
|
|
42
|
-
|
|
60
|
+
if not os.path.exists(pos + "output"):
|
|
61
|
+
os.mkdir(pos + "output")
|
|
43
62
|
|
|
44
|
-
if not os.path.exists(pos+os.sep.join(["output","tables"])):
|
|
45
|
-
|
|
63
|
+
if not os.path.exists(pos + os.sep.join(["output", "tables"])):
|
|
64
|
+
os.mkdir(pos + os.sep.join(["output", "tables"]))
|
|
46
65
|
|
|
47
|
-
if mode.lower()=="target" or mode.lower()=="targets":
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
66
|
+
if mode.lower() == "target" or mode.lower() == "targets":
|
|
67
|
+
label_folder = "labels_targets"
|
|
68
|
+
instruction_file = os.sep.join(["configs", "tracking_instructions_targets.json"])
|
|
69
|
+
napari_name = "napari_target_trajectories.npy"
|
|
70
|
+
table_name = "trajectories_targets.csv"
|
|
52
71
|
|
|
53
|
-
elif mode.lower()=="effector" or mode.lower()=="effectors":
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
72
|
+
elif mode.lower() == "effector" or mode.lower() == "effectors":
|
|
73
|
+
label_folder = "labels_effectors"
|
|
74
|
+
instruction_file = os.sep.join(["configs", "tracking_instructions_effectors.json"])
|
|
75
|
+
napari_name = "napari_effector_trajectories.npy"
|
|
76
|
+
table_name = "trajectories_effectors.csv"
|
|
58
77
|
|
|
59
78
|
# Locate experiment config
|
|
60
79
|
parent1 = Path(pos).parent
|
|
61
80
|
expfolder = parent1.parent
|
|
62
|
-
config = PurePath(expfolder,Path("config.ini"))
|
|
63
|
-
assert os.path.exists(
|
|
81
|
+
config = PurePath(expfolder, Path("config.ini"))
|
|
82
|
+
assert os.path.exists(
|
|
83
|
+
config
|
|
84
|
+
), "The configuration file for the experiment could not be located. Abort."
|
|
64
85
|
|
|
65
86
|
print(f"Position: {extract_position_name(pos)}...")
|
|
66
|
-
print("Configuration file: ",config)
|
|
87
|
+
print("Configuration file: ", config)
|
|
67
88
|
print(f"Population: {mode}...")
|
|
68
89
|
|
|
69
90
|
# from exp config fetch spatial calib, channel names
|
|
@@ -78,76 +99,82 @@ channel_names, channel_indices = extract_experiment_channels(expfolder)
|
|
|
78
99
|
nbr_channels = len(channel_names)
|
|
79
100
|
|
|
80
101
|
# from tracking instructions, fetch btrack config, features, haralick, clean_traj, idea: fetch custom timeline?
|
|
81
|
-
print(
|
|
82
|
-
instr_path = PurePath(expfolder,Path(f"{instruction_file}"))
|
|
102
|
+
print("Looking for tracking instruction file...")
|
|
103
|
+
instr_path = PurePath(expfolder, Path(f"{instruction_file}"))
|
|
83
104
|
if os.path.exists(instr_path):
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
105
|
+
print(f"Tracking instruction file successfully loaded...")
|
|
106
|
+
with open(instr_path, "r") as f:
|
|
107
|
+
instructions = json.load(f)
|
|
108
|
+
btrack_config = interpret_tracking_configuration(instructions["btrack_config_path"])
|
|
109
|
+
|
|
110
|
+
if "features" in instructions:
|
|
111
|
+
features = instructions["features"]
|
|
112
|
+
else:
|
|
113
|
+
features = None
|
|
114
|
+
|
|
115
|
+
if "mask_channels" in instructions:
|
|
116
|
+
mask_channels = instructions["mask_channels"]
|
|
117
|
+
else:
|
|
118
|
+
mask_channels = None
|
|
119
|
+
|
|
120
|
+
if "haralick_options" in instructions:
|
|
121
|
+
haralick_options = instructions["haralick_options"]
|
|
122
|
+
else:
|
|
123
|
+
haralick_options = None
|
|
124
|
+
|
|
125
|
+
if "post_processing_options" in instructions:
|
|
126
|
+
post_processing_options = instructions["post_processing_options"]
|
|
127
|
+
else:
|
|
128
|
+
post_processing_options = None
|
|
129
|
+
|
|
130
|
+
btrack_option = True
|
|
131
|
+
if "btrack_option" in instructions:
|
|
132
|
+
btrack_option = instructions["btrack_option"]
|
|
133
|
+
search_range = None
|
|
134
|
+
if "search_range" in instructions:
|
|
135
|
+
search_range = instructions["search_range"]
|
|
136
|
+
memory = None
|
|
137
|
+
if "memory" in instructions:
|
|
138
|
+
memory = instructions["memory"]
|
|
118
139
|
else:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
140
|
+
print(
|
|
141
|
+
"Tracking instructions could not be located... Using a standard bTrack motion model instead..."
|
|
142
|
+
)
|
|
143
|
+
btrack_config = interpret_tracking_configuration(None)
|
|
144
|
+
features = None
|
|
145
|
+
mask_channels = None
|
|
146
|
+
haralick_options = None
|
|
147
|
+
post_processing_options = None
|
|
148
|
+
btrack_option = True
|
|
149
|
+
memory = None
|
|
150
|
+
search_range = None
|
|
128
151
|
if features is None:
|
|
129
|
-
|
|
152
|
+
features = []
|
|
130
153
|
|
|
131
154
|
# from pos fetch labels
|
|
132
|
-
label_path = natsorted(glob(pos+f"{label_folder}"+os.sep+"*.tif"))
|
|
133
|
-
if len(label_path)>0:
|
|
134
|
-
|
|
155
|
+
label_path = natsorted(glob(pos + f"{label_folder}" + os.sep + "*.tif"))
|
|
156
|
+
if len(label_path) > 0:
|
|
157
|
+
print(f"Found {len(label_path)} segmented frames...")
|
|
135
158
|
else:
|
|
136
|
-
|
|
137
|
-
|
|
159
|
+
print(
|
|
160
|
+
f"No segmented frames have been found. Please run segmentation first. Abort..."
|
|
161
|
+
)
|
|
162
|
+
os.abort()
|
|
138
163
|
|
|
139
164
|
# Do this if features or Haralick is not None, else don't need stack
|
|
140
165
|
try:
|
|
141
|
-
|
|
166
|
+
file = glob(pos + os.sep.join(["movie", f"{movie_prefix}*.tif"]))[0]
|
|
142
167
|
except IndexError:
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
168
|
+
print(
|
|
169
|
+
"Movie could not be found. Check the prefix. If you intended to measure texture or tone, this will not be performed."
|
|
170
|
+
)
|
|
171
|
+
file = None
|
|
172
|
+
haralick_option = None
|
|
173
|
+
features = drop_tonal_features(features)
|
|
147
174
|
|
|
148
175
|
len_movie_auto = auto_load_number_of_frames(file)
|
|
149
176
|
if len_movie_auto is not None:
|
|
150
|
-
|
|
177
|
+
len_movie = len_movie_auto
|
|
151
178
|
|
|
152
179
|
img_num_channels = _get_img_num_per_channel(channel_indices, len_movie, nbr_channels)
|
|
153
180
|
|
|
@@ -156,45 +183,57 @@ img_num_channels = _get_img_num_per_channel(channel_indices, len_movie, nbr_chan
|
|
|
156
183
|
#######################################
|
|
157
184
|
|
|
158
185
|
timestep_dataframes = []
|
|
159
|
-
features_log=f
|
|
160
|
-
mask_channels_log=f
|
|
161
|
-
haralick_option_log=f
|
|
162
|
-
post_processing_option_log=f
|
|
163
|
-
log_list=[
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
186
|
+
features_log = f"features: {features}"
|
|
187
|
+
mask_channels_log = f"mask_channels: {mask_channels}"
|
|
188
|
+
haralick_option_log = f"haralick_options: {haralick_options}"
|
|
189
|
+
post_processing_option_log = f"post_processing_options: {post_processing_options}"
|
|
190
|
+
log_list = [
|
|
191
|
+
features_log,
|
|
192
|
+
mask_channels_log,
|
|
193
|
+
haralick_option_log,
|
|
194
|
+
post_processing_option_log,
|
|
195
|
+
]
|
|
196
|
+
log = "\n".join(log_list)
|
|
197
|
+
|
|
198
|
+
with open(pos + f"log_{mode}.json", "a") as f:
|
|
199
|
+
f.write(f"{datetime.datetime.now()} TRACK \n")
|
|
200
|
+
f.write(log + "\n")
|
|
169
201
|
|
|
170
202
|
|
|
171
203
|
if not btrack_option:
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
204
|
+
features = []
|
|
205
|
+
channel_names = None
|
|
206
|
+
haralick_options = None
|
|
175
207
|
|
|
176
208
|
|
|
177
209
|
def measure_index(indices):
|
|
178
210
|
|
|
179
|
-
|
|
211
|
+
props = []
|
|
212
|
+
|
|
213
|
+
for t in tqdm(indices, desc="frame"):
|
|
214
|
+
|
|
215
|
+
# Load channels at time t
|
|
216
|
+
img = _load_frames_to_measure(file, indices=img_num_channels[:, t])
|
|
217
|
+
lbl = locate_labels(pos, population=mode, frames=t)
|
|
218
|
+
if lbl is None:
|
|
219
|
+
continue
|
|
180
220
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
221
|
+
df_props = measure_features(
|
|
222
|
+
img,
|
|
223
|
+
lbl,
|
|
224
|
+
features=features + ["centroid"],
|
|
225
|
+
border_dist=None,
|
|
226
|
+
channels=channel_names,
|
|
227
|
+
haralick_options=haralick_options,
|
|
228
|
+
verbose=False,
|
|
229
|
+
)
|
|
230
|
+
df_props.rename(columns={"centroid-1": "x", "centroid-0": "y"}, inplace=True)
|
|
231
|
+
df_props["t"] = int(t)
|
|
188
232
|
|
|
189
|
-
|
|
190
|
-
channels=channel_names, haralick_options=haralick_options, verbose=False,
|
|
191
|
-
)
|
|
192
|
-
df_props.rename(columns={'centroid-1': 'x', 'centroid-0': 'y'},inplace=True)
|
|
193
|
-
df_props['t'] = int(t)
|
|
233
|
+
props.append(df_props)
|
|
194
234
|
|
|
195
|
-
|
|
235
|
+
return props
|
|
196
236
|
|
|
197
|
-
return props
|
|
198
237
|
|
|
199
238
|
print(f"Measuring features with {n_threads} thread(s)...")
|
|
200
239
|
|
|
@@ -204,54 +243,64 @@ chunks = np.array_split(indices, n_threads)
|
|
|
204
243
|
|
|
205
244
|
timestep_dataframes = []
|
|
206
245
|
with concurrent.futures.ThreadPoolExecutor() as executor:
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
246
|
+
results = executor.map(measure_index, chunks)
|
|
247
|
+
try:
|
|
248
|
+
for i, return_value in enumerate(results):
|
|
249
|
+
print(f"Thread {i} completed...")
|
|
250
|
+
timestep_dataframes.extend(return_value)
|
|
251
|
+
except Exception as e:
|
|
252
|
+
print("Exception: ", e)
|
|
214
253
|
|
|
215
|
-
print(
|
|
254
|
+
print("Features successfully measured...")
|
|
216
255
|
|
|
217
|
-
df = pd.concat(timestep_dataframes)
|
|
256
|
+
df = pd.concat(timestep_dataframes)
|
|
218
257
|
df.reset_index(inplace=True, drop=True)
|
|
219
258
|
|
|
220
259
|
df = _mask_intensity_measurements(df, mask_channels)
|
|
221
260
|
|
|
222
261
|
# do tracking
|
|
223
262
|
if btrack_option:
|
|
224
|
-
|
|
263
|
+
tracker = "bTrack"
|
|
225
264
|
else:
|
|
226
|
-
|
|
265
|
+
tracker = "trackpy"
|
|
227
266
|
|
|
228
267
|
print(f"Start the tracking step using the {tracker} tracker...")
|
|
229
268
|
|
|
230
|
-
trajectories, napari_data = track(
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
269
|
+
trajectories, napari_data = track(
|
|
270
|
+
None,
|
|
271
|
+
configuration=btrack_config,
|
|
272
|
+
objects=df,
|
|
273
|
+
spatial_calibration=spatial_calibration,
|
|
274
|
+
channel_names=channel_names,
|
|
275
|
+
return_napari_data=True,
|
|
276
|
+
optimizer_options={"tm_lim": int(12e4)},
|
|
277
|
+
track_kwargs={"step_size": 100},
|
|
278
|
+
clean_trajectories_kwargs=post_processing_options,
|
|
279
|
+
volume=(shape_x, shape_y),
|
|
280
|
+
btrack_option=btrack_option,
|
|
281
|
+
search_range=search_range,
|
|
282
|
+
memory=memory,
|
|
283
|
+
)
|
|
244
284
|
print(f"Tracking successfully performed...")
|
|
245
285
|
|
|
246
286
|
# out trajectory table, create POSITION_X_um, POSITION_Y_um, TIME_min (new ones)
|
|
247
287
|
# Save napari data # deprecated, should disappear progressively
|
|
248
|
-
np.save(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
288
|
+
np.save(
|
|
289
|
+
pos + os.sep.join(["output", "tables", napari_name]), napari_data, allow_pickle=True
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
trajectories.to_csv(pos + os.sep.join(["output", "tables", table_name]), index=False)
|
|
293
|
+
print(
|
|
294
|
+
f"Trajectory table successfully exported in {os.sep.join(['output', 'tables'])}..."
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
if os.path.exists(
|
|
298
|
+
pos + os.sep.join(["output", "tables", table_name.replace(".csv", ".pkl")])
|
|
299
|
+
):
|
|
300
|
+
os.remove(
|
|
301
|
+
pos + os.sep.join(["output", "tables", table_name.replace(".csv", ".pkl")])
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
del trajectories
|
|
305
|
+
del napari_data
|
|
306
|
+
gc.collect()
|