microlive 1.0.11__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.
- microlive/__init__.py +50 -0
- microlive/data/__init__.py +0 -0
- microlive/data/icons/__init__.py +0 -0
- microlive/data/icons/icon_micro.png +0 -0
- microlive/data/models/__init__.py +0 -0
- microlive/gui/__init__.py +1 -0
- microlive/gui/app.py +16340 -0
- microlive/gui/main.py +86 -0
- microlive/gui/micro_mac.command +18 -0
- microlive/gui/micro_windows.bat +24 -0
- microlive/imports.py +209 -0
- microlive/microscopy.py +13321 -0
- microlive/ml_spot_detection.py +252 -0
- microlive/pipelines/__init__.py +17 -0
- microlive/pipelines/pipeline_FRAP.py +1225 -0
- microlive/pipelines/pipeline_folding_efficiency.py +297 -0
- microlive/pipelines/pipeline_particle_tracking.py +489 -0
- microlive/pipelines/pipeline_spot_detection_no_tracking.py +368 -0
- microlive/utils/__init__.py +13 -0
- microlive/utils/device.py +99 -0
- microlive/utils/resources.py +60 -0
- microlive-1.0.11.dist-info/METADATA +361 -0
- microlive-1.0.11.dist-info/RECORD +26 -0
- microlive-1.0.11.dist-info/WHEEL +4 -0
- microlive-1.0.11.dist-info/entry_points.txt +2 -0
- microlive-1.0.11.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
"""Pipeline module for MicroLive.
|
|
2
|
+
|
|
3
|
+
This module is part of the microlive package.
|
|
4
|
+
"""
|
|
5
|
+
from microlive.imports import *
|
|
6
|
+
|
|
7
|
+
def pipeline_particle_tracking(data_folder_path, selected_image, channels_spots, max_spots_for_threshold=100000,
|
|
8
|
+
show_plot=True, channels_cytosol=None, channels_nucleus=None,memory=1,
|
|
9
|
+
min_length_trajectory=5, yx_spot_size_in_px=5, z_spot_size_in_px=2, maximum_spots_cluster=4,cluster_radius_nm =500,
|
|
10
|
+
MINIMAL_SNR=0.5, diameter_cytosol=300, diameter_nucleus=200,
|
|
11
|
+
segmentation_selection_metric='max_area',recalculate_mask=False,optimization_segmentation_method='diameter_segmentation',
|
|
12
|
+
pretrained_model_cyto_segmentation=None,use_watershed=False,list_images_to_process=None,save_3d_visualization=False,
|
|
13
|
+
max_percentage_empty_data_in_trajectory=0.1,particle_detection_threshold=None,save_croparray=False,
|
|
14
|
+
apply_photobleaching_correction=False,photobleaching_mode='inside_cell',use_maximum_projection=False,
|
|
15
|
+
max_lag_for_MSD=30,step_size_in_sec=1,separate_clusters_and_spots=False,maximum_range_search_pixels=10,results_folder_path=None,
|
|
16
|
+
calculate_MSD=True,calculate_correlations=True):
|
|
17
|
+
# Read images and metadata
|
|
18
|
+
# detect if the data is a lif file
|
|
19
|
+
list_images, list_names, pixel_xy_um, voxel_z_um, channel_names, number_color_channels, list_time_intervals, bit_depth = \
|
|
20
|
+
mi.ReadLif(data_folder_path, show_metadata=False, save_tif=False, save_png=False, format='TZYXC').read()
|
|
21
|
+
# Prepare full list of images and set up indices to process
|
|
22
|
+
list_images_complete = list_images.copy()
|
|
23
|
+
if list_images_to_process is not None:
|
|
24
|
+
selected_indices = [i for i in range(len(list_names)) if list_names[i] in list_images_to_process]
|
|
25
|
+
if use_maximum_projection:
|
|
26
|
+
# use the maximum projection in Z. but keep the image shape with only one Z slice
|
|
27
|
+
list_images = [np.max(list_images[i], axis=1, keepdims=True) for i in selected_indices]
|
|
28
|
+
else:
|
|
29
|
+
list_images = [list_images[i] for i in selected_indices]
|
|
30
|
+
else:
|
|
31
|
+
selected_indices = range(len(list_names))
|
|
32
|
+
if use_maximum_projection:
|
|
33
|
+
list_images = [np.max(img, axis=1, keepdims=True) for img in list_images]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# If selected_image is None, process all images
|
|
38
|
+
if selected_image is None:
|
|
39
|
+
list_df, list_masks, list_images_tested, list_diffusion_coefficient = [], [], [], []
|
|
40
|
+
|
|
41
|
+
#for idx in range(len(list_images)):
|
|
42
|
+
for idx in range(len(list_images_complete)):
|
|
43
|
+
if idx not in selected_indices:
|
|
44
|
+
continue
|
|
45
|
+
df, masks,image,diffusion_coefficient = process_single_image(
|
|
46
|
+
data_folder_path=data_folder_path,
|
|
47
|
+
selected_image=idx,
|
|
48
|
+
channels_spots=channels_spots,
|
|
49
|
+
max_spots_for_threshold=max_spots_for_threshold,
|
|
50
|
+
show_plot=show_plot,
|
|
51
|
+
channels_cytosol=channels_cytosol,
|
|
52
|
+
channels_nucleus=channels_nucleus,
|
|
53
|
+
min_length_trajectory=min_length_trajectory,
|
|
54
|
+
yx_spot_size_in_px=yx_spot_size_in_px,
|
|
55
|
+
z_spot_size_in_px = z_spot_size_in_px,
|
|
56
|
+
maximum_spots_cluster=maximum_spots_cluster,
|
|
57
|
+
cluster_radius_nm=cluster_radius_nm,
|
|
58
|
+
MINIMAL_SNR=MINIMAL_SNR,
|
|
59
|
+
diameter_cytosol=diameter_cytosol,
|
|
60
|
+
diameter_nucleus=diameter_nucleus,
|
|
61
|
+
segmentation_selection_metric=segmentation_selection_metric,
|
|
62
|
+
list_images=list_images_complete,
|
|
63
|
+
list_names=list_names,
|
|
64
|
+
pixel_xy_um=pixel_xy_um,
|
|
65
|
+
voxel_z_um=voxel_z_um,
|
|
66
|
+
channel_names=channel_names,
|
|
67
|
+
image_time_interval=list_time_intervals[idx],
|
|
68
|
+
recalculate_mask=recalculate_mask,
|
|
69
|
+
optimization_segmentation_method=optimization_segmentation_method,
|
|
70
|
+
pretrained_model_cyto_segmentation=pretrained_model_cyto_segmentation,
|
|
71
|
+
use_watershed=use_watershed,
|
|
72
|
+
save_3d_visualization=save_3d_visualization,
|
|
73
|
+
apply_photobleaching_correction=apply_photobleaching_correction,
|
|
74
|
+
photobleaching_mode=photobleaching_mode,
|
|
75
|
+
use_maximum_projection=use_maximum_projection,
|
|
76
|
+
max_lag_for_MSD = max_lag_for_MSD,
|
|
77
|
+
step_size_in_sec=step_size_in_sec,
|
|
78
|
+
separate_clusters_and_spots=separate_clusters_and_spots,
|
|
79
|
+
maximum_range_search_pixels=maximum_range_search_pixels,
|
|
80
|
+
max_percentage_empty_data_in_trajectory=max_percentage_empty_data_in_trajectory,
|
|
81
|
+
memory=memory,
|
|
82
|
+
particle_detection_threshold=particle_detection_threshold,
|
|
83
|
+
results_folder_path=results_folder_path,
|
|
84
|
+
calculate_MSD=calculate_MSD,
|
|
85
|
+
calculate_correlations=calculate_correlations,
|
|
86
|
+
save_croparray=save_croparray,
|
|
87
|
+
)
|
|
88
|
+
#if df is None:
|
|
89
|
+
# if the df is None or empty, continue to the next image
|
|
90
|
+
if df.empty:
|
|
91
|
+
continue
|
|
92
|
+
# rename the field image_id to idx
|
|
93
|
+
df['image_id'] = idx
|
|
94
|
+
list_df.append(df)
|
|
95
|
+
list_masks.append(masks)
|
|
96
|
+
list_images_tested.append(image)
|
|
97
|
+
list_diffusion_coefficient.append(diffusion_coefficient)
|
|
98
|
+
|
|
99
|
+
if len(list_df) >1 :
|
|
100
|
+
final_df = pd.concat(list_df, ignore_index=True)
|
|
101
|
+
else:
|
|
102
|
+
final_df = df
|
|
103
|
+
return final_df, list_df, list_masks, list_images_tested, list_diffusion_coefficient
|
|
104
|
+
else:
|
|
105
|
+
# Process single image
|
|
106
|
+
df,masks,image, diffusion_coefficient= process_single_image(
|
|
107
|
+
data_folder_path=data_folder_path,
|
|
108
|
+
selected_image=selected_image,
|
|
109
|
+
channels_spots=channels_spots,
|
|
110
|
+
max_spots_for_threshold=max_spots_for_threshold,
|
|
111
|
+
show_plot=show_plot,
|
|
112
|
+
channels_cytosol=channels_cytosol,
|
|
113
|
+
channels_nucleus=channels_nucleus,
|
|
114
|
+
min_length_trajectory=min_length_trajectory,
|
|
115
|
+
yx_spot_size_in_px=yx_spot_size_in_px,
|
|
116
|
+
z_spot_size_in_px = z_spot_size_in_px,
|
|
117
|
+
maximum_spots_cluster=maximum_spots_cluster,
|
|
118
|
+
cluster_radius_nm=cluster_radius_nm,
|
|
119
|
+
MINIMAL_SNR=MINIMAL_SNR,
|
|
120
|
+
diameter_cytosol=diameter_cytosol,
|
|
121
|
+
diameter_nucleus=diameter_nucleus,
|
|
122
|
+
segmentation_selection_metric=segmentation_selection_metric,
|
|
123
|
+
list_images=list_images,
|
|
124
|
+
list_names=list_names[idx],
|
|
125
|
+
pixel_xy_um=pixel_xy_um,
|
|
126
|
+
voxel_z_um=voxel_z_um,
|
|
127
|
+
channel_names=channel_names,
|
|
128
|
+
image_time_interval = list_time_intervals[selected_image],
|
|
129
|
+
recalculate_mask=recalculate_mask,
|
|
130
|
+
optimization_segmentation_method=optimization_segmentation_method,
|
|
131
|
+
pretrained_model_cyto_segmentation=pretrained_model_cyto_segmentation,
|
|
132
|
+
use_watershed=use_watershed,
|
|
133
|
+
save_3d_visualization=save_3d_visualization,
|
|
134
|
+
apply_photobleaching_correction=apply_photobleaching_correction,
|
|
135
|
+
photobleaching_mode=photobleaching_mode,
|
|
136
|
+
use_maximum_projection=use_maximum_projection,
|
|
137
|
+
max_lag_for_MSD = max_lag_for_MSD,
|
|
138
|
+
step_size_in_sec=step_size_in_sec,
|
|
139
|
+
separate_clusters_and_spots=separate_clusters_and_spots,
|
|
140
|
+
maximum_range_search_pixels=maximum_range_search_pixels,
|
|
141
|
+
max_percentage_empty_data_in_trajectory=max_percentage_empty_data_in_trajectory,
|
|
142
|
+
memory=memory,
|
|
143
|
+
particle_detection_threshold=particle_detection_threshold,
|
|
144
|
+
results_folder_path=results_folder_path,
|
|
145
|
+
calculate_MSD=calculate_MSD,
|
|
146
|
+
calculate_correlations=calculate_correlations,
|
|
147
|
+
save_croparray=save_croparray,
|
|
148
|
+
)
|
|
149
|
+
return df, [df], [masks], [image], [diffusion_coefficient]
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@mi.Utilities().metadata_decorator(metadata_folder_func=mi.Utilities().get_metadata_folder,exclude_args=['list_images',]) # exclude_args=['list_images', 'list_names' ]
|
|
157
|
+
def process_single_image(data_folder_path, selected_image, channels_spots, max_spots_for_threshold=100000,
|
|
158
|
+
show_plot=True, channels_cytosol=None, channels_nucleus=None,memory=1,
|
|
159
|
+
min_length_trajectory=5, yx_spot_size_in_px=5, z_spot_size_in_px=2 , maximum_spots_cluster=4,cluster_radius_nm=500,
|
|
160
|
+
MINIMAL_SNR=0.5, diameter_cytosol=300, diameter_nucleus=200, segmentation_selection_metric='area',
|
|
161
|
+
list_images=None, list_names=None, pixel_xy_um=None, voxel_z_um=None,
|
|
162
|
+
channel_names=None, optimization_segmentation_method='diameter_segmentation',
|
|
163
|
+
recalculate_mask=False,use_watershed=False, pretrained_model_cyto_segmentation=None,particle_detection_threshold=None,save_croparray=False,
|
|
164
|
+
image_time_interval=None,save_3d_visualization=False,apply_photobleaching_correction=False,photobleaching_mode='inside_cell',max_percentage_empty_data_in_trajectory=0.1,
|
|
165
|
+
use_maximum_projection=False,max_lag_for_MSD=30,step_size_in_sec=1,separate_clusters_and_spots=False,maximum_range_search_pixels=10,results_folder_path=None,
|
|
166
|
+
calculate_MSD=True,calculate_correlations=True):
|
|
167
|
+
# Ensure lists are properly formatted
|
|
168
|
+
channels_spots = [channels_spots] if not isinstance(channels_spots, list) else channels_spots
|
|
169
|
+
channels_cytosol = [channels_cytosol] if not isinstance(channels_cytosol, list) else channels_cytosol
|
|
170
|
+
channels_nucleus = [channels_nucleus] if not isinstance(channels_nucleus, list) else channels_nucleus
|
|
171
|
+
|
|
172
|
+
# Convert pixel and voxel sizes to nm
|
|
173
|
+
pixel_xy_nm = int(pixel_xy_um * 1000)
|
|
174
|
+
voxel_z_nm = int(voxel_z_um * 1000)
|
|
175
|
+
list_voxels = [voxel_z_nm, pixel_xy_nm]
|
|
176
|
+
list_spot_size_px = [z_spot_size_in_px, yx_spot_size_in_px]
|
|
177
|
+
# print a line
|
|
178
|
+
print('--------------------------------------------------')
|
|
179
|
+
print(f'Processing image: {list_names[selected_image]}')
|
|
180
|
+
tested_image = list_images[selected_image] # TZYXC
|
|
181
|
+
original_tested_image = tested_image.copy()
|
|
182
|
+
# Creating the results folder
|
|
183
|
+
results_name = 'results_' + data_folder_path.stem + '_cell_id_' + str(selected_image)
|
|
184
|
+
current_dir = pathlib.Path().absolute()
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
if results_folder_path is not None:
|
|
188
|
+
# ensure that results_folder_path is a Path object
|
|
189
|
+
if not isinstance(results_folder_path, pathlib.Path):
|
|
190
|
+
results_folder_path = pathlib.Path(results_folder_path)
|
|
191
|
+
results_folder = results_folder_path.joinpath(results_name)
|
|
192
|
+
else:
|
|
193
|
+
results_folder = current_dir.joinpath('results_live_cell', results_name)
|
|
194
|
+
results_folder.mkdir(parents=True, exist_ok=True)
|
|
195
|
+
mi.Utilities().clear_folder_except_substring(results_folder, 'mask')
|
|
196
|
+
# Plot the original image
|
|
197
|
+
plot_name_original = results_folder.joinpath('original_image.png')
|
|
198
|
+
suptitle=f'Image: {data_folder_path.stem[:16]} - {list_names[selected_image]} - Cell_ID: {selected_image}'
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
mi.Plots().plot_images(
|
|
202
|
+
image_ZYXC=tested_image[0],
|
|
203
|
+
figsize=(12, 5),
|
|
204
|
+
show_plot=show_plot,
|
|
205
|
+
use_maximum_projection=True,
|
|
206
|
+
use_gaussian_filter=True,
|
|
207
|
+
cmap='binary',
|
|
208
|
+
min_max_percentile=[0.5, 99.9],
|
|
209
|
+
show_gird=False,
|
|
210
|
+
save_plots=True,
|
|
211
|
+
plot_name=plot_name_original,
|
|
212
|
+
suptitle=suptitle
|
|
213
|
+
)
|
|
214
|
+
# Read or create masks
|
|
215
|
+
mask_file_name = 'mask_' + data_folder_path.stem + '_image_' + str(selected_image) + '.tif'
|
|
216
|
+
mask_file_path = results_folder.joinpath(mask_file_name)
|
|
217
|
+
path_mask_exist = os.path.exists(str(mask_file_path))
|
|
218
|
+
if path_mask_exist and recalculate_mask is False:
|
|
219
|
+
masks = imread(str(mask_file_path)).astype(bool)
|
|
220
|
+
else:
|
|
221
|
+
# Use Cellpose to create masks
|
|
222
|
+
if use_watershed:
|
|
223
|
+
masks_complete_cells = mi.CellSegmentationWatershed(np.max(tested_image[:,:,:,:,channels_cytosol[0]],
|
|
224
|
+
axis=(0,1)), footprint_size=2, ).apply_watershed()
|
|
225
|
+
else:
|
|
226
|
+
masks_complete_cells, _, _ = mi.CellSegmentation(
|
|
227
|
+
tested_image[0],
|
|
228
|
+
channels_cytosol=channels_cytosol,
|
|
229
|
+
channels_nucleus=channels_nucleus,
|
|
230
|
+
diameter_cytosol=diameter_cytosol,
|
|
231
|
+
diameter_nucleus=diameter_nucleus,
|
|
232
|
+
optimization_segmentation_method=optimization_segmentation_method,
|
|
233
|
+
remove_fragmented_cells=False,
|
|
234
|
+
show_plot=show_plot,
|
|
235
|
+
image_name=None,
|
|
236
|
+
NUMBER_OF_CORES=1,
|
|
237
|
+
selection_metric=segmentation_selection_metric,
|
|
238
|
+
pretrained_model_cyto_segmentation = pretrained_model_cyto_segmentation
|
|
239
|
+
).calculate_masks()
|
|
240
|
+
# Selecting the mask that is in the center of the image
|
|
241
|
+
center_y = masks_complete_cells.shape[0] // 2
|
|
242
|
+
center_x = masks_complete_cells.shape[1] // 2
|
|
243
|
+
selected_mask_id = masks_complete_cells[center_y, center_x]
|
|
244
|
+
if selected_mask_id > 0:
|
|
245
|
+
masks = masks_complete_cells == selected_mask_id
|
|
246
|
+
else:
|
|
247
|
+
# Select the largest mask that is not the background mask (0)
|
|
248
|
+
mask_labels = np.unique(masks_complete_cells)
|
|
249
|
+
mask_sizes = [(label, np.sum(masks_complete_cells == label)) for label in mask_labels if label != 0]
|
|
250
|
+
if mask_sizes:
|
|
251
|
+
selected_mask_id = max(mask_sizes, key=lambda x: x[1])[0]
|
|
252
|
+
masks = masks_complete_cells == selected_mask_id
|
|
253
|
+
else:
|
|
254
|
+
masks = np.zeros_like(masks_complete_cells, dtype=bool)
|
|
255
|
+
# Save the mask
|
|
256
|
+
masks = masks.astype(np.uint8)
|
|
257
|
+
tifffile.imwrite(str(mask_file_path), masks, dtype='uint8')
|
|
258
|
+
|
|
259
|
+
if apply_photobleaching_correction:
|
|
260
|
+
file_path_photobleacing = results_folder.joinpath('photobleaching.png')
|
|
261
|
+
corrected_image = mi.Photobleaching(image_TZYXC=tested_image,mask_YX=masks, show_plot=False, mode= photobleaching_mode,plot_name=file_path_photobleacing).apply_photobleaching_correction() #mi.PhotobleachingCorrection(tested_image).apply_correction()
|
|
262
|
+
|
|
263
|
+
else:
|
|
264
|
+
corrected_image = tested_image
|
|
265
|
+
# Calculate the threshold for spot detection
|
|
266
|
+
plot_name_threshold = results_folder.joinpath('threshold_spot_detection.png')
|
|
267
|
+
|
|
268
|
+
if particle_detection_threshold is None:
|
|
269
|
+
starting_threshold = mi.Utilities().calculate_threshold_for_spot_detection(
|
|
270
|
+
corrected_image, list_spot_size_px, list_voxels, channels_spots,
|
|
271
|
+
max_spots_for_threshold=max_spots_for_threshold,
|
|
272
|
+
show_plot=True,plot_name=plot_name_threshold
|
|
273
|
+
)
|
|
274
|
+
else:
|
|
275
|
+
starting_threshold = [particle_detection_threshold]*len(channels_spots)
|
|
276
|
+
|
|
277
|
+
# Run the particle tracking
|
|
278
|
+
try:
|
|
279
|
+
list_dataframes_trajectories, _ = mi.ParticleTracking(
|
|
280
|
+
image=corrected_image,
|
|
281
|
+
channels_spots=channels_spots,
|
|
282
|
+
masks=masks,
|
|
283
|
+
list_voxels=list_voxels,
|
|
284
|
+
memory=memory,
|
|
285
|
+
channels_cytosol=channels_cytosol,
|
|
286
|
+
channels_nucleus=channels_nucleus,
|
|
287
|
+
min_length_trajectory=min_length_trajectory,
|
|
288
|
+
threshold_for_spot_detection=starting_threshold,
|
|
289
|
+
yx_spot_size_in_px=yx_spot_size_in_px,
|
|
290
|
+
z_spot_size_in_px=z_spot_size_in_px,
|
|
291
|
+
maximum_spots_cluster=maximum_spots_cluster,
|
|
292
|
+
cluster_radius_nm = cluster_radius_nm,
|
|
293
|
+
separate_clusters_and_spots=separate_clusters_and_spots,
|
|
294
|
+
maximum_range_search_pixels=maximum_range_search_pixels,
|
|
295
|
+
).run()
|
|
296
|
+
except Exception as e:
|
|
297
|
+
print(f'Error: {e}')
|
|
298
|
+
return pd.DataFrame(), masks, original_tested_image, None
|
|
299
|
+
#df_tracking = list_dataframes_trajectories[0]
|
|
300
|
+
df_tracking = list_dataframes_trajectories[0]
|
|
301
|
+
|
|
302
|
+
if len(df_tracking)==0:
|
|
303
|
+
return pd.DataFrame(), masks, original_tested_image, None
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
if len(list_dataframes_trajectories) > 1:
|
|
307
|
+
for i in range(1, len(list_dataframes_trajectories)):
|
|
308
|
+
df_tracking = pd.concat([df_tracking, list_dataframes_trajectories[i]], ignore_index=True)
|
|
309
|
+
df_tracking = df_tracking.reset_index(drop=True)
|
|
310
|
+
#print(df_tracking)
|
|
311
|
+
# Plot histograms for the SNR
|
|
312
|
+
selected_field = 'snr' # options are: psf_sigma, snr, 'spot_int'
|
|
313
|
+
plot_name_snr = results_folder.joinpath('spots_' + selected_field + '.png')
|
|
314
|
+
mean_snr = mi.Plots().plot_histograms_from_df(
|
|
315
|
+
df_tracking,
|
|
316
|
+
selected_field=selected_field,
|
|
317
|
+
figsize=(8, 2),
|
|
318
|
+
plot_name=plot_name_snr,
|
|
319
|
+
bin_count=60,
|
|
320
|
+
save_plot=True,
|
|
321
|
+
list_colors=channel_names,
|
|
322
|
+
remove_outliers=True
|
|
323
|
+
)
|
|
324
|
+
# Plot histograms for the spot intensity
|
|
325
|
+
selected_field = 'spot_int'
|
|
326
|
+
plot_name_int = results_folder.joinpath('spots_' + selected_field + '.png')
|
|
327
|
+
mean_int = mi.Plots().plot_histograms_from_df(
|
|
328
|
+
df_tracking,
|
|
329
|
+
selected_field=selected_field,
|
|
330
|
+
figsize=(8, 2),
|
|
331
|
+
plot_name=plot_name_int,
|
|
332
|
+
bin_count=60,
|
|
333
|
+
save_plot=True,
|
|
334
|
+
list_colors=channel_names,
|
|
335
|
+
remove_outliers=True
|
|
336
|
+
)
|
|
337
|
+
# Remove tracks with low SNR in the tracking channel
|
|
338
|
+
if MINIMAL_SNR is not None:
|
|
339
|
+
array_selected_field = mi.Utilities().df_trajectories_to_array(
|
|
340
|
+
dataframe=df_tracking,
|
|
341
|
+
selected_field=selected_field + '_ch_' + str(channels_spots[0]),
|
|
342
|
+
fill_value='nans'
|
|
343
|
+
)
|
|
344
|
+
mean_snr = np.nanmean(array_selected_field, axis=1)
|
|
345
|
+
indices_low_quality_tracks = np.where(mean_snr < MINIMAL_SNR)[0]
|
|
346
|
+
df_tracking = df_tracking[~df_tracking['particle'].isin(indices_low_quality_tracks)]
|
|
347
|
+
df_tracking = df_tracking.reset_index(drop=True)
|
|
348
|
+
df_tracking['particle'] = df_tracking.groupby('particle').ngroup()
|
|
349
|
+
# Plot image intensity histogram
|
|
350
|
+
|
|
351
|
+
masked_data = corrected_image * masks[np.newaxis, np.newaxis, :, :, np.newaxis].astype(float)
|
|
352
|
+
for i in range(len(channels_spots)):
|
|
353
|
+
#plot_name_histogram = results_folder.joinpath('pixel_histogram_in_cell.png')
|
|
354
|
+
plot_name_histogram = results_folder.joinpath('pixel_histogram_in_cell_'+str(channels_spots[i])+'.png')
|
|
355
|
+
mi.Plots().plot_image_pixel_intensity_distribution(
|
|
356
|
+
image=np.mean(masked_data, axis=(0, 1)),
|
|
357
|
+
figsize=(8, 2),
|
|
358
|
+
bins=100,
|
|
359
|
+
remove_outliers=True,
|
|
360
|
+
remove_zeros=True,
|
|
361
|
+
save_plots=True,
|
|
362
|
+
plot_name=plot_name_histogram,
|
|
363
|
+
single_color=None,
|
|
364
|
+
list_colors=channel_names,
|
|
365
|
+
tracking_channel=channels_spots[0],
|
|
366
|
+
threshold_tracking=starting_threshold[i]
|
|
367
|
+
)
|
|
368
|
+
# Plot original image and tracks
|
|
369
|
+
suptitle = f'Image: {data_folder_path.stem[:16]} - {list_names[selected_image]} - Cell_ID: {selected_image}'
|
|
370
|
+
plot_name_original_image_and_tracks = results_folder.joinpath('original_image_tracking.png')
|
|
371
|
+
mi.Plots().plot_images(
|
|
372
|
+
image_ZYXC=corrected_image[0],
|
|
373
|
+
df=df_tracking,
|
|
374
|
+
masks=masks,
|
|
375
|
+
show_trajectories=True,
|
|
376
|
+
suptitle=suptitle,
|
|
377
|
+
figsize=(12, 3),
|
|
378
|
+
show_plot=True,
|
|
379
|
+
selected_time=0,
|
|
380
|
+
use_maximum_projection=True,
|
|
381
|
+
use_gaussian_filter=True,
|
|
382
|
+
cmap='binary',
|
|
383
|
+
min_max_percentile=[0.05, 99.95],
|
|
384
|
+
show_gird=False,
|
|
385
|
+
save_plots=True,
|
|
386
|
+
plot_name=plot_name_original_image_and_tracks
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
# Combine the original image and the image with tracks
|
|
390
|
+
plot_name_complete_image = results_folder.joinpath('complete_image_tracking.png')
|
|
391
|
+
mi.Utilities().combine_images_vertically([plot_name_original, plot_name_original_image_and_tracks], plot_name_complete_image, delete_originals=True)
|
|
392
|
+
|
|
393
|
+
# Save the DataFrame
|
|
394
|
+
df_tracking.to_csv(results_folder.joinpath('tracking_results.csv'), index=False)
|
|
395
|
+
PLOT_FILTERED_IMAGES = True
|
|
396
|
+
normalize_each_particle = True
|
|
397
|
+
crop_size = yx_spot_size_in_px + 5 # 3 pixels for the border
|
|
398
|
+
# add 5 pixels to crop_size, check if the crop_size is odd, if not, add 1
|
|
399
|
+
if crop_size % 2 == 0:
|
|
400
|
+
crop_size += 1
|
|
401
|
+
selected_time_point = None
|
|
402
|
+
#if PLOT_FILTERED_IMAGES:
|
|
403
|
+
filtered_image = mi.Utilities().gaussian_laplace_filter_image(corrected_image, list_spot_size_px, list_voxels)
|
|
404
|
+
croparray_filtered, mean_crop_filtered, first_appearance, crop_size = mi.CropArray(image=filtered_image, df_crops=df_tracking, crop_size=crop_size, remove_outliers=False, max_percentile=99.95,selected_time_point=selected_time_point,normalize_each_particle=normalize_each_particle).run()
|
|
405
|
+
#else:
|
|
406
|
+
# croparray_filtered, mean_crop_filtered, first_appearance, crop_size = mi.CropArray(image=tested_image, df_crops=df_tracking, crop_size=crop_size, remove_outliers=False, max_percentile=99.9,selected_time_point=selected_time_point,normalize_each_particle=normalize_each_particle).run()
|
|
407
|
+
# Plot all crops
|
|
408
|
+
if save_croparray:
|
|
409
|
+
path_crop_array = results_folder.joinpath('crop_array.png')
|
|
410
|
+
mi.Plots().plot_croparray(croparray_filtered, crop_size, save_plots=True,plot_name= path_crop_array,suptitle=None,show_particle_labels=True, cmap='binary_r',max_percentile = 99) # flag_vector=flag_vector
|
|
411
|
+
# plot pair of crops
|
|
412
|
+
plot_name_crops_filter = results_folder.joinpath('crops.png')
|
|
413
|
+
mi.Plots().plot_matrix_pair_crops (mean_crop_filtered, crop_size,save_plots=True,plot_name=plot_name_crops_filter) # flag_vector=flag_vector
|
|
414
|
+
# Calculate the Mean Squared Displacement
|
|
415
|
+
plot_name_MSD = results_folder.joinpath('MSD_plot.png')
|
|
416
|
+
|
|
417
|
+
#max_lag_for_MSD = 30
|
|
418
|
+
if image_time_interval is None:
|
|
419
|
+
image_time_interval = step_size_in_sec
|
|
420
|
+
print(f'Warning: The image_time_interval was not provided. Using the step_size_in_sec as the image_time_interval: {step_size_in_sec} seconds.')
|
|
421
|
+
else:
|
|
422
|
+
image_time_interval = float(image_time_interval)
|
|
423
|
+
# print a warning message indicating that we are using the step_size_in_sec as the image_time_interval
|
|
424
|
+
|
|
425
|
+
if calculate_MSD:
|
|
426
|
+
diffusion_coefficient, em, time_range, model_fit, trackpy_df = mi.ParticleMotion(df_tracking,
|
|
427
|
+
microns_per_pixel=pixel_xy_um,
|
|
428
|
+
step_size_in_sec=image_time_interval,
|
|
429
|
+
max_lagtime=max_lag_for_MSD,
|
|
430
|
+
show_plot=True,
|
|
431
|
+
remove_drift=False,
|
|
432
|
+
plot_name=plot_name_MSD).calculate_msd()
|
|
433
|
+
else:
|
|
434
|
+
diffusion_coefficient = None
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
if calculate_correlations:
|
|
438
|
+
# calculate and plot the autocorrelation
|
|
439
|
+
array_ch0= mi.Utilities().df_trajectories_to_array(dataframe=df_tracking, selected_field='spot_int_ch_0', fill_value='nans')
|
|
440
|
+
|
|
441
|
+
if 'spot_int_ch_1' in df_tracking.columns:
|
|
442
|
+
array_ch1= mi.Utilities().df_trajectories_to_array(dataframe=df_tracking, selected_field='spot_int_ch_1', fill_value='nans')
|
|
443
|
+
intensity_array_ch0_short, intensity_array_ch1_short = mi.Utilities().shift_trajectories(array_ch0, array_ch1,max_percentage_empty_data_in_trajectory=max_percentage_empty_data_in_trajectory)
|
|
444
|
+
else:
|
|
445
|
+
array_ch1 = None
|
|
446
|
+
intensity_array_ch0_short = mi.Utilities().shift_trajectories(array_ch0,max_percentage_empty_data_in_trajectory=max_percentage_empty_data_in_trajectory)
|
|
447
|
+
intensity_array_ch1_short = None
|
|
448
|
+
|
|
449
|
+
plot_name_intensity_matrix = results_folder.joinpath('intensity_matrix.png')
|
|
450
|
+
mi.Plots().plot_matrix_sample_time(intensity_array_ch0_short, intensity_array_ch1_short,plot_name=plot_name_intensity_matrix)
|
|
451
|
+
|
|
452
|
+
plot_name_AC_ch0 = results_folder.joinpath('AC_plot_ch0.png')
|
|
453
|
+
mean_correlation_ch0, std_correlation_ch0, lags_ch0, correlations_array_ch0,dwell_time_ch0 = mi.Correlation(primary_data=intensity_array_ch0_short, max_lag=None,
|
|
454
|
+
nan_handling='ignore',shift_data=True,return_full=False,
|
|
455
|
+
time_interval_between_frames_in_seconds=image_time_interval,
|
|
456
|
+
show_plot=True,start_lag=1,fit_type='exponential',
|
|
457
|
+
use_linear_projection_for_lag_0=True,save_plots=True,plot_name=plot_name_AC_ch0).run()
|
|
458
|
+
if array_ch1 is not None:
|
|
459
|
+
plot_name_AC_ch1 = results_folder.joinpath('AC_plot_ch1.png')
|
|
460
|
+
mean_correlation_ch1, std_correlation_ch1, lags_ch1, correlations_array_ch1,dwell_time_ch1 = mi.Correlation(primary_data=intensity_array_ch1_short, max_lag=None,
|
|
461
|
+
nan_handling='ignore',shift_data=True,return_full=False,
|
|
462
|
+
time_interval_between_frames_in_seconds=image_time_interval,
|
|
463
|
+
show_plot=True,start_lag=1,fit_type='exponential',
|
|
464
|
+
use_linear_projection_for_lag_0=True,save_plots=True,plot_name=plot_name_AC_ch1).run()
|
|
465
|
+
|
|
466
|
+
# Plot cross-correlation
|
|
467
|
+
plot_name_cross_correlation = results_folder.joinpath('cross_correlation.png')
|
|
468
|
+
mean_cross_correlation, std_cross_correlation, lags_cross_correlation, cross_correlations_array, max_lag = mi.Correlation(primary_data=intensity_array_ch0_short, secondary_data=intensity_array_ch1_short,
|
|
469
|
+
max_lag=None, nan_handling='ignore', shift_data=False, return_full=True,
|
|
470
|
+
time_interval_between_frames_in_seconds=image_time_interval,show_plot=True,
|
|
471
|
+
save_plots=True,plot_name=plot_name_cross_correlation).run()
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
# plot napari visualizer
|
|
475
|
+
if save_3d_visualization:
|
|
476
|
+
mask_expanded = masks[np.newaxis, np.newaxis, :, :, np.newaxis]
|
|
477
|
+
masked_image_TZYXC = filtered_image * mask_expanded
|
|
478
|
+
# Apply Gaussian filter to reduce background noise
|
|
479
|
+
#from scipy.ndimage import gaussian_filter
|
|
480
|
+
masked_image_TZYXC = gaussian_filter(masked_image_TZYXC, sigma=1)
|
|
481
|
+
# Remove extreme values from the image
|
|
482
|
+
masked_image_TZYXC = mi.RemoveExtrema(masked_image_TZYXC, min_percentile=0.001, max_percentile=99.995).remove_outliers()
|
|
483
|
+
plot_name_3d_visualizer = str(results_folder.joinpath('image_3d.gif'))
|
|
484
|
+
mi.Plots().Napari_Visualizer(masked_image_TZYXC, df_tracking, z_correction=7, channels_spots=0, plot_name=plot_name_3d_visualizer)
|
|
485
|
+
|
|
486
|
+
# print the process has finished for the selected image
|
|
487
|
+
print(f'Image {list_names[selected_image]} has been processed.')
|
|
488
|
+
|
|
489
|
+
return df_tracking, masks, original_tested_image, diffusion_coefficient
|