celldetective 1.3.2__py3-none-any.whl → 1.3.4__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/__main__.py +30 -4
- celldetective/_version.py +1 -1
- celldetective/extra_properties.py +21 -0
- celldetective/filters.py +15 -2
- celldetective/gui/InitWindow.py +28 -34
- celldetective/gui/analyze_block.py +3 -498
- celldetective/gui/classifier_widget.py +1 -1
- celldetective/gui/control_panel.py +100 -29
- celldetective/gui/generic_signal_plot.py +35 -18
- celldetective/gui/gui_utils.py +143 -2
- celldetective/gui/layouts.py +7 -6
- celldetective/gui/measurement_options.py +38 -43
- celldetective/gui/plot_measurements.py +5 -13
- celldetective/gui/plot_signals_ui.py +30 -30
- celldetective/gui/process_block.py +66 -197
- celldetective/gui/retrain_segmentation_model_options.py +3 -1
- celldetective/gui/signal_annotator.py +50 -32
- celldetective/gui/signal_annotator2.py +7 -4
- celldetective/gui/styles.py +13 -0
- celldetective/gui/survival_ui.py +8 -21
- celldetective/gui/tableUI.py +1 -2
- celldetective/gui/thresholds_gui.py +195 -205
- celldetective/gui/viewers.py +262 -12
- celldetective/io.py +85 -11
- celldetective/measure.py +128 -88
- celldetective/models/segmentation_effectors/ricm_bf_all_last/config_input.json +79 -0
- celldetective/models/segmentation_effectors/ricm_bf_all_last/ricm_bf_all_last +0 -0
- celldetective/models/segmentation_effectors/ricm_bf_all_last/training_instructions.json +37 -0
- celldetective/models/segmentation_effectors/test-transfer/config_input.json +39 -0
- celldetective/models/segmentation_effectors/test-transfer/test-transfer +0 -0
- celldetective/neighborhood.py +0 -2
- celldetective/scripts/measure_cells.py +21 -9
- celldetective/signals.py +77 -66
- celldetective/tracking.py +19 -13
- {celldetective-1.3.2.dist-info → celldetective-1.3.4.dist-info}/METADATA +12 -10
- {celldetective-1.3.2.dist-info → celldetective-1.3.4.dist-info}/RECORD +41 -36
- {celldetective-1.3.2.dist-info → celldetective-1.3.4.dist-info}/WHEEL +1 -1
- tests/test_qt.py +5 -3
- {celldetective-1.3.2.dist-info → celldetective-1.3.4.dist-info}/LICENSE +0 -0
- {celldetective-1.3.2.dist-info → celldetective-1.3.4.dist-info}/entry_points.txt +0 -0
- {celldetective-1.3.2.dist-info → celldetective-1.3.4.dist-info}/top_level.txt +0 -0
celldetective/measure.py
CHANGED
|
@@ -15,6 +15,7 @@ import subprocess
|
|
|
15
15
|
from math import ceil
|
|
16
16
|
|
|
17
17
|
from skimage.draw import disk as dsk
|
|
18
|
+
from skimage.feature import blob_dog, blob_log
|
|
18
19
|
|
|
19
20
|
from celldetective.utils import rename_intensity_column, create_patch_mask, remove_redundant_features, \
|
|
20
21
|
remove_trajectory_measurements, contour_of_instance_segmentation, extract_cols_from_query, step_function, interpolate_nan
|
|
@@ -325,12 +326,7 @@ def measure_features(img, label, features=['area', 'intensity_mean'], channels=N
|
|
|
325
326
|
for index, channel in enumerate(channels):
|
|
326
327
|
if channel == spot_detection['channel']:
|
|
327
328
|
ind = index
|
|
328
|
-
|
|
329
|
-
threshold=spot_detection['threshold'])
|
|
330
|
-
df_spots = pd.DataFrame.from_dict(blobs, orient='index',
|
|
331
|
-
columns=['count', 'spot_mean_intensity']).reset_index()
|
|
332
|
-
# Rename columns
|
|
333
|
-
df_spots.columns = ['label', 'spot_count', 'spot_mean_intensity']
|
|
329
|
+
df_spots = blob_detection(img, label, diameter=spot_detection['diameter'],threshold=spot_detection['threshold'], channel_name=spot_detection['channel'], target_channel=ind)
|
|
334
330
|
|
|
335
331
|
if normalisation_list:
|
|
336
332
|
for norm in normalisation_list:
|
|
@@ -362,47 +358,27 @@ def measure_features(img, label, features=['area', 'intensity_mean'], channels=N
|
|
|
362
358
|
props = regionprops_table(label, intensity_image=img, properties=feats, extra_properties=extra_props_list)
|
|
363
359
|
df_props = pd.DataFrame(props)
|
|
364
360
|
if spot_detection is not None:
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
# if spot_detection is not None:
|
|
372
|
-
# for index, channel in enumerate(channels):
|
|
373
|
-
# if channel == spot_detection['channel']:
|
|
374
|
-
# ind = index
|
|
375
|
-
# blobs = blob_detection(img[:, :, ind], label, diameter=spot_detection['diameter'],
|
|
376
|
-
# threshold=spot_detection['threshold'])
|
|
377
|
-
# df_spots = pd.DataFrame.from_dict(blobs, orient='index', columns=['count', 'spot_mean_intensity']).reset_index()
|
|
378
|
-
# # Rename columns
|
|
379
|
-
# df_spots.columns = ['label', 'spot_count', 'spot_mean_intensity']
|
|
380
|
-
# df_props = df_props.merge(df_spots, how='outer', on='label')
|
|
381
|
-
# df_props['spot_count'] = df_props['spot_count'].replace(np.nan, 0)
|
|
382
|
-
# df_props['spot_mean_intensity'] = df_props['spot_mean_intensity'].replace(np.nan, 0)
|
|
383
|
-
|
|
361
|
+
if df_spots is not None:
|
|
362
|
+
df_props = df_props.merge(df_spots, how='outer', on='label',suffixes=('_delme', ''))
|
|
363
|
+
df_props = df_props[[c for c in df_props.columns if not c.endswith('_delme')]]
|
|
384
364
|
|
|
385
365
|
if border_dist is not None:
|
|
386
366
|
# automatically drop all non intensity features
|
|
387
367
|
intensity_features_test = [('intensity' in s and 'centroid' not in s and 'peripheral' not in s) for s in
|
|
388
368
|
features]
|
|
389
369
|
intensity_features = list(np.array(features)[np.array(intensity_features_test)])
|
|
390
|
-
# intensity_extra = [(s in extra_props_list)for s in intensity_features]
|
|
391
|
-
# print(intensity_extra)
|
|
392
370
|
intensity_extra = []
|
|
393
371
|
for s in intensity_features:
|
|
394
372
|
if s in extra_props:
|
|
395
373
|
intensity_extra.append(getattr(extra_properties, s))
|
|
396
374
|
intensity_features.remove(s)
|
|
397
|
-
|
|
398
|
-
# If no intensity feature was passed still measure mean intensity
|
|
375
|
+
|
|
399
376
|
if len(intensity_features) == 0:
|
|
400
377
|
if verbose:
|
|
401
378
|
print('No intensity feature was passed... Adding mean intensity for edge measurement...')
|
|
402
379
|
intensity_features = np.append(intensity_features, 'intensity_mean')
|
|
403
380
|
intensity_features = list(np.append(intensity_features, 'label'))
|
|
404
381
|
|
|
405
|
-
# Remove extra intensity properties from border measurements
|
|
406
382
|
new_intensity_features = intensity_features.copy()
|
|
407
383
|
for int_feat in intensity_features:
|
|
408
384
|
if int_feat in extra_props:
|
|
@@ -439,8 +415,10 @@ def measure_features(img, label, features=['area', 'intensity_mean'], channels=N
|
|
|
439
415
|
if haralick_options is not None:
|
|
440
416
|
try:
|
|
441
417
|
df_haralick = compute_haralick_features(img, label, channels=channels, **haralick_options)
|
|
442
|
-
|
|
443
|
-
|
|
418
|
+
if df_haralick is not None:
|
|
419
|
+
df_haralick = df_haralick.rename(columns={"cell_id": "label"})
|
|
420
|
+
df_props = df_props.merge(df_haralick, how='outer', on='label', suffixes=('_delme', ''))
|
|
421
|
+
df_props = df_props[[c for c in df_props.columns if not c.endswith('_delme')]]
|
|
444
422
|
except Exception as e:
|
|
445
423
|
print(e)
|
|
446
424
|
pass
|
|
@@ -541,6 +519,10 @@ def compute_haralick_features(img, labels, channels=None, target_channel=0, scal
|
|
|
541
519
|
if len(img.shape)==3:
|
|
542
520
|
img = img[:,:,target_channel]
|
|
543
521
|
|
|
522
|
+
# Routine to skip black frames
|
|
523
|
+
if np.percentile(img.flatten(),99.9)==0.0:
|
|
524
|
+
return None
|
|
525
|
+
|
|
544
526
|
img = interpolate_nan(img)
|
|
545
527
|
|
|
546
528
|
# Rescale image and mask
|
|
@@ -916,67 +898,125 @@ def normalise_by_cell(image, labels, distance=5, model='median', operation='subt
|
|
|
916
898
|
return normalised_frame
|
|
917
899
|
|
|
918
900
|
|
|
919
|
-
def
|
|
920
|
-
|
|
921
|
-
|
|
901
|
+
def extract_blobs_in_image(image, label, diameter, threshold=0., method="log"):
|
|
902
|
+
|
|
903
|
+
if np.percentile(image.flatten(),99.9)==0.0:
|
|
904
|
+
return None
|
|
922
905
|
|
|
923
|
-
|
|
924
|
-
- image (numpy.ndarray): The input image data.
|
|
925
|
-
- label (numpy.ndarray): An array specifying labeled regions in the image.
|
|
926
|
-
- threshold (float): The threshold value for blob detection.
|
|
927
|
-
- diameter (float): The expected diameter of blobs.
|
|
906
|
+
dilated_image = ndimage.grey_dilation(label, footprint=disk(10))
|
|
928
907
|
|
|
929
|
-
|
|
930
|
-
|
|
908
|
+
masked_image = image.copy()
|
|
909
|
+
masked_image[np.where((dilated_image == 0)|(image!=image))] = 0
|
|
910
|
+
min_sigma = (1 / (1 + math.sqrt(2))) * diameter
|
|
911
|
+
max_sigma = math.sqrt(2) * min_sigma
|
|
912
|
+
if method=="dog":
|
|
913
|
+
blobs = blob_dog(masked_image, threshold=threshold, min_sigma=min_sigma, max_sigma=max_sigma, overlap=0.75)
|
|
914
|
+
elif method=="log":
|
|
915
|
+
blobs = blob_log(masked_image, threshold=threshold, min_sigma=min_sigma, max_sigma=max_sigma, overlap=0.75)
|
|
916
|
+
# Exclude spots outside of cell masks
|
|
917
|
+
mask = np.array([label[int(y), int(x)] != 0 for y, x, _ in blobs])
|
|
918
|
+
if np.any(mask):
|
|
919
|
+
blobs_filtered = blobs[mask]
|
|
920
|
+
else:
|
|
921
|
+
blobs_filtered=[]
|
|
931
922
|
|
|
932
|
-
|
|
933
|
-
and detects blobs within the region using the Difference of Gaussians (DoG) method. Detected blobs are filtered
|
|
934
|
-
based on the specified threshold and expected diameter. The function returns a dictionary containing the number of
|
|
935
|
-
detected blobs and their mean intensity for each labeled region.
|
|
923
|
+
return blobs_filtered
|
|
936
924
|
|
|
937
|
-
Example:
|
|
938
|
-
>>> image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
|
939
|
-
>>> label = np.array([[0, 1, 1], [2, 2, 0], [3, 3, 0]])
|
|
940
|
-
>>> threshold = 0.1
|
|
941
|
-
>>> diameter = 5.0
|
|
942
|
-
>>> result = blob_detection(image, label, threshold, diameter)
|
|
943
|
-
>>> print(result)
|
|
944
|
-
{1: [1, 4.0], 2: [0, nan], 3: [0, nan]}
|
|
945
925
|
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
926
|
+
def blob_detection(image, label, diameter, threshold=0., channel_name=None, target_channel=0, method="log"):
|
|
927
|
+
|
|
928
|
+
image = image[:, :, target_channel].copy()
|
|
929
|
+
if np.percentile(image.flatten(),99.9)==0.0:
|
|
930
|
+
return None
|
|
931
|
+
|
|
932
|
+
detections = []
|
|
933
|
+
blobs_filtered = extract_blobs_in_image(image, label, diameter, threshold=threshold)
|
|
934
|
+
|
|
935
|
+
for lbl in np.unique(label):
|
|
936
|
+
if lbl>0:
|
|
937
|
+
|
|
938
|
+
blob_selection = np.array([label[int(y), int(x)] == lbl for y, x, _ in blobs_filtered])
|
|
939
|
+
if np.any(blob_selection):
|
|
940
|
+
# if any spot
|
|
941
|
+
blobs_in_cell = blobs_filtered[blob_selection]
|
|
942
|
+
n_spots = len(blobs_in_cell)
|
|
943
|
+
binary_blobs = np.zeros_like(label)
|
|
944
|
+
for blob in blobs_in_cell:
|
|
945
|
+
y, x, sig = blob
|
|
946
|
+
r = np.sqrt(2)*sig
|
|
947
|
+
rr, cc = dsk((y, x), r, shape=binary_blobs.shape)
|
|
948
|
+
binary_blobs[rr, cc] = 1
|
|
949
|
+
intensity_mean = np.nanmean(image[binary_blobs==1].flatten())
|
|
950
|
+
else:
|
|
951
|
+
n_spots = 0
|
|
952
|
+
intensity_mean = np.nan
|
|
953
|
+
detections.append({'label': lbl, f'{channel_name}_spot_count': n_spots, f'{channel_name}_mean_spot_intensity': intensity_mean})
|
|
954
|
+
detections = pd.DataFrame(detections)
|
|
955
|
+
|
|
956
|
+
return detections
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
# def blob_detectionv0(image, label, threshold, diameter):
|
|
960
|
+
# """
|
|
961
|
+
# Perform blob detection on an image based on labeled regions.
|
|
962
|
+
|
|
963
|
+
# Parameters:
|
|
964
|
+
# - image (numpy.ndarray): The input image data.
|
|
965
|
+
# - label (numpy.ndarray): An array specifying labeled regions in the image.
|
|
966
|
+
# - threshold (float): The threshold value for blob detection.
|
|
967
|
+
# - diameter (float): The expected diameter of blobs.
|
|
968
|
+
|
|
969
|
+
# Returns:
|
|
970
|
+
# - dict: A dictionary containing information about detected blobs.
|
|
971
|
+
|
|
972
|
+
# This function performs blob detection on an image based on labeled regions. It iterates over each labeled region
|
|
973
|
+
# and detects blobs within the region using the Difference of Gaussians (DoG) method. Detected blobs are filtered
|
|
974
|
+
# based on the specified threshold and expected diameter. The function returns a dictionary containing the number of
|
|
975
|
+
# detected blobs and their mean intensity for each labeled region.
|
|
976
|
+
|
|
977
|
+
# Example:
|
|
978
|
+
# >>> image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
|
979
|
+
# >>> label = np.array([[0, 1, 1], [2, 2, 0], [3, 3, 0]])
|
|
980
|
+
# >>> threshold = 0.1
|
|
981
|
+
# >>> diameter = 5.0
|
|
982
|
+
# >>> result = blob_detection(image, label, threshold, diameter)
|
|
983
|
+
# >>> print(result)
|
|
984
|
+
# {1: [1, 4.0], 2: [0, nan], 3: [0, nan]}
|
|
985
|
+
|
|
986
|
+
# Note:
|
|
987
|
+
# - Blobs are detected using the Difference of Gaussians (DoG) method.
|
|
988
|
+
# - Detected blobs are filtered based on the specified threshold and expected diameter.
|
|
989
|
+
# - The returned dictionary contains information about the number of detected blobs and their mean intensity
|
|
990
|
+
# for each labeled region.
|
|
991
|
+
# """
|
|
992
|
+
# blob_labels = {}
|
|
993
|
+
# dilated_image = ndimage.grey_dilation(label, footprint=disk(10))
|
|
994
|
+
# for mask_index in np.unique(label):
|
|
995
|
+
# if mask_index == 0:
|
|
996
|
+
# continue
|
|
997
|
+
# removed_background = image.copy()
|
|
998
|
+
# one_mask = label.copy()
|
|
999
|
+
# one_mask[np.where(label != mask_index)] = 0
|
|
1000
|
+
# dilated_copy = dilated_image.copy()
|
|
1001
|
+
# dilated_copy[np.where(dilated_image != mask_index)] = 0
|
|
1002
|
+
# removed_background[np.where(dilated_copy == 0)] = 0
|
|
1003
|
+
# min_sigma = (1 / (1 + math.sqrt(2))) * diameter
|
|
1004
|
+
# max_sigma = math.sqrt(2) * min_sigma
|
|
1005
|
+
# blobs = blob_dog(removed_background, threshold=threshold, min_sigma=min_sigma,
|
|
1006
|
+
# max_sigma=max_sigma)
|
|
1007
|
+
|
|
1008
|
+
# mask = np.array([one_mask[int(y), int(x)] != 0 for y, x, r in blobs])
|
|
1009
|
+
# if not np.any(mask):
|
|
1010
|
+
# continue
|
|
1011
|
+
# blobs_filtered = blobs[mask]
|
|
1012
|
+
# binary_blobs = np.zeros_like(label)
|
|
1013
|
+
# for blob in blobs_filtered:
|
|
1014
|
+
# y, x, r = blob
|
|
1015
|
+
# rr, cc = dsk((y, x), r, shape=binary_blobs.shape)
|
|
1016
|
+
# binary_blobs[rr, cc] = 1
|
|
1017
|
+
# spot_intensity = regionprops_table(binary_blobs, removed_background, ['intensity_mean'])
|
|
1018
|
+
# blob_labels[mask_index] = [blobs_filtered.shape[0], spot_intensity['intensity_mean'][0]]
|
|
1019
|
+
# return blob_labels
|
|
980
1020
|
|
|
981
1021
|
### Classification ####
|
|
982
1022
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"channels": [
|
|
3
|
+
"adhesion_channel",
|
|
4
|
+
"brightfield_channel"
|
|
5
|
+
],
|
|
6
|
+
"diameter": 30.0,
|
|
7
|
+
"cellprob_threshold": 0.0,
|
|
8
|
+
"flow_threshold": 0.4,
|
|
9
|
+
"normalization_percentile": [
|
|
10
|
+
false,
|
|
11
|
+
true
|
|
12
|
+
],
|
|
13
|
+
"normalization_clip": [
|
|
14
|
+
true,
|
|
15
|
+
true
|
|
16
|
+
],
|
|
17
|
+
"normalization_values": [
|
|
18
|
+
[
|
|
19
|
+
0.75,
|
|
20
|
+
1.25
|
|
21
|
+
],
|
|
22
|
+
[
|
|
23
|
+
1.0,
|
|
24
|
+
99.0
|
|
25
|
+
]
|
|
26
|
+
],
|
|
27
|
+
"model_type": "cellpose",
|
|
28
|
+
"spatial_calibration": 0.2,
|
|
29
|
+
"dataset": {
|
|
30
|
+
"train": [
|
|
31
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_404_0066_roi_429_935_159_649.tif",
|
|
32
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_200_0003_roi_457_991_5_488.tif",
|
|
33
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-11-23-analysis-2024_508_0008.tif",
|
|
34
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-11-23-analysis-2024_305_0075.tif",
|
|
35
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_302_0063_roi_405_865_462_937.tif",
|
|
36
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_506_0066_roi_473_944_494_953.tif",
|
|
37
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_202_0027_roi_557_998_3_447.tif",
|
|
38
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_208_0027_roi_600_997_5_387.tif",
|
|
39
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_206_0023_roi_251_707_249_666.tif",
|
|
40
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_201_0017_roi_324_961_23_596.tif",
|
|
41
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_102_0053_roi_511_996_4_433.tif",
|
|
42
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_403_0009_roi_554_996_460_994.tif",
|
|
43
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-11-23-analysis-2024_508_0066.tif",
|
|
44
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_507_0066_roi_492_998_9_474.tif",
|
|
45
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_202_0029_roi_177_746_4_533.tif",
|
|
46
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_203_0060_roi_369_906_119_648.tif",
|
|
47
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_304_0025.tif",
|
|
48
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_207_0030_roi_152_661_531_998.tif",
|
|
49
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_105_0018_roi_510_954_13_422.tif",
|
|
50
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_507_0016_roi_29_585_462_996.tif",
|
|
51
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_504_0066_roi_305_866_382_909.tif",
|
|
52
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_605_0060_roi_6_479_351_847.tif",
|
|
53
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-11-23-analysis-2024_403_0008.tif",
|
|
54
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_203_0029_roi_3_376_622_1000.tif",
|
|
55
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_102_0094.tif",
|
|
56
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_202_0055_roi_1_514_68_597.tif",
|
|
57
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_206_0000.tif",
|
|
58
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_302_0023_roi_295_768_6_437.tif",
|
|
59
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-11-23-analysis-2024_805_0081.tif",
|
|
60
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_605_0010_roi_341_847_162_673.tif",
|
|
61
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_205_0002_roi_70_569_6_490.tif",
|
|
62
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_200_0055_roi_99_778_341_986.tif",
|
|
63
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-11-23-analysis-2024_802_0040.tif",
|
|
64
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_206_0028_roi_2_426_487_995.tif",
|
|
65
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_706_0042_roi_99_515_11_394.tif"
|
|
66
|
+
],
|
|
67
|
+
"validation": [
|
|
68
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_201_0003_roi_501_957_576_1000.tif",
|
|
69
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-11-23-analysis-2024_603_0032.tif",
|
|
70
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_706_0030_roi_323_824_488_995.tif",
|
|
71
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_202_0014_roi_258_711_504_959.tif",
|
|
72
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_207_0007_roi_119_611_5_451.tif",
|
|
73
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_206_0030.tif",
|
|
74
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_207_0055_roi_519_989_6_429.tif",
|
|
75
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-03-03-analysis-2024_506_0053_roi_190_724_13_490.tif",
|
|
76
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects/Marie-20-06-analysis-2024_300_0047_roi_416_985_436_972.tif"
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"model_name": "ricm_bf_all_last",
|
|
3
|
+
"model_type": "cellpose",
|
|
4
|
+
"pretrained": null,
|
|
5
|
+
"spatial_calibration": 0.2,
|
|
6
|
+
"channel_option": [
|
|
7
|
+
"adhesion_channel",
|
|
8
|
+
"brightfield_channel"
|
|
9
|
+
],
|
|
10
|
+
"normalization_percentile": [
|
|
11
|
+
false,
|
|
12
|
+
true
|
|
13
|
+
],
|
|
14
|
+
"normalization_clip": [
|
|
15
|
+
true,
|
|
16
|
+
true
|
|
17
|
+
],
|
|
18
|
+
"normalization_values": [
|
|
19
|
+
[
|
|
20
|
+
0.75,
|
|
21
|
+
1.25
|
|
22
|
+
],
|
|
23
|
+
[
|
|
24
|
+
1.0,
|
|
25
|
+
99.0
|
|
26
|
+
]
|
|
27
|
+
],
|
|
28
|
+
"ds": [
|
|
29
|
+
"/home/limozin/Downloads/dataset-marie-all-objects(1)/dataset-marie-all-objects"
|
|
30
|
+
],
|
|
31
|
+
"augmentation_factor": 3.0,
|
|
32
|
+
"validation_split": 0.2,
|
|
33
|
+
"learning_rate": 0.008,
|
|
34
|
+
"batch_size": 8,
|
|
35
|
+
"epochs": 3000,
|
|
36
|
+
"target_directory": "/home/limozin/Documents/GitHub/celldetective/celldetective/models/segmentation_effectors"
|
|
37
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"channels": [
|
|
3
|
+
"brightfield_channel",
|
|
4
|
+
"None"
|
|
5
|
+
],
|
|
6
|
+
"diameter": 30.0,
|
|
7
|
+
"cellprob_threshold": 0.0,
|
|
8
|
+
"flow_threshold": 0.4,
|
|
9
|
+
"normalization_percentile": [
|
|
10
|
+
true,
|
|
11
|
+
true
|
|
12
|
+
],
|
|
13
|
+
"normalization_clip": [
|
|
14
|
+
true,
|
|
15
|
+
true
|
|
16
|
+
],
|
|
17
|
+
"normalization_values": [
|
|
18
|
+
[
|
|
19
|
+
1.0,
|
|
20
|
+
99.0
|
|
21
|
+
],
|
|
22
|
+
[
|
|
23
|
+
1.0,
|
|
24
|
+
99.0
|
|
25
|
+
]
|
|
26
|
+
],
|
|
27
|
+
"model_type": "cellpose",
|
|
28
|
+
"spatial_calibration": 0.36666666666666664,
|
|
29
|
+
"dataset": {
|
|
30
|
+
"train": [
|
|
31
|
+
"/home/torro/Documents/Experiments/Marie-03-03-analysis-2024/annotations_effectors/Marie-03-03-analysis-2024_206_0028_roi_2_426_487_995.tif",
|
|
32
|
+
"/home/torro/Documents/Experiments/Marie-03-03-analysis-2024/annotations_effectors/Marie-03-03-analysis-2024_203_0029_roi_3_376_622_1000.tif",
|
|
33
|
+
"/home/torro/Documents/Experiments/Marie-03-03-analysis-2024/annotations_effectors/Marie-03-03-analysis-2024_208_0027_roi_600_997_5_387.tif"
|
|
34
|
+
],
|
|
35
|
+
"validation": [
|
|
36
|
+
"/home/torro/Documents/Experiments/Marie-03-03-analysis-2024/annotations_effectors/Marie-03-03-analysis-2024_206_0023_roi_251_707_249_666.tif"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
Binary file
|
celldetective/neighborhood.py
CHANGED
|
@@ -7,8 +7,6 @@ from celldetective.utils import contour_of_instance_segmentation, extract_identi
|
|
|
7
7
|
from scipy.spatial.distance import cdist
|
|
8
8
|
from celldetective.io import locate_labels, get_position_pickle, get_position_table
|
|
9
9
|
|
|
10
|
-
import matplotlib.pyplot as plt
|
|
11
|
-
|
|
12
10
|
abs_path = os.sep.join([os.path.split(os.path.dirname(os.path.realpath(__file__)))[0], 'celldetective'])
|
|
13
11
|
|
|
14
12
|
|
|
@@ -5,7 +5,7 @@ Copright © 2022 Laboratoire Adhesion et Inflammation, Authored by Remy Torro.
|
|
|
5
5
|
import argparse
|
|
6
6
|
import os
|
|
7
7
|
import json
|
|
8
|
-
from celldetective.io import auto_load_number_of_frames, load_frames
|
|
8
|
+
from celldetective.io import auto_load_number_of_frames, load_frames, fix_missing_labels, locate_labels
|
|
9
9
|
from celldetective.utils import extract_experiment_channels, ConfigSectionMap, _get_img_num_per_channel, extract_experiment_channels
|
|
10
10
|
from celldetective.utils import remove_redundant_features, remove_trajectory_measurements
|
|
11
11
|
from celldetective.measure import drop_tonal_features, measure_features, measure_isotropic_intensity
|
|
@@ -16,7 +16,6 @@ import numpy as np
|
|
|
16
16
|
import pandas as pd
|
|
17
17
|
from natsort import natsorted
|
|
18
18
|
from art import tprint
|
|
19
|
-
from tifffile import imread
|
|
20
19
|
import threading
|
|
21
20
|
import datetime
|
|
22
21
|
|
|
@@ -165,6 +164,8 @@ else:
|
|
|
165
164
|
features += ['centroid']
|
|
166
165
|
do_iso_intensities = False
|
|
167
166
|
|
|
167
|
+
# if 'centroid' not in features:
|
|
168
|
+
# features += ['centroid']
|
|
168
169
|
|
|
169
170
|
# if (features is not None) and (trajectories is not None):
|
|
170
171
|
# features = remove_redundant_features(features,
|
|
@@ -176,6 +177,12 @@ len_movie_auto = auto_load_number_of_frames(file)
|
|
|
176
177
|
if len_movie_auto is not None:
|
|
177
178
|
len_movie = len_movie_auto
|
|
178
179
|
|
|
180
|
+
if label_path is not None and file is not None:
|
|
181
|
+
test = len(label_path)==len_movie
|
|
182
|
+
if not test:
|
|
183
|
+
fix_missing_labels(pos, population=mode, prefix=movie_prefix)
|
|
184
|
+
label_path = natsorted(glob(os.sep.join([pos, label_folder, '*.tif'])))
|
|
185
|
+
|
|
179
186
|
img_num_channels = _get_img_num_per_channel(channel_indices, len_movie, nbr_channels)
|
|
180
187
|
|
|
181
188
|
|
|
@@ -203,6 +210,8 @@ if trajectories is None:
|
|
|
203
210
|
if 'label' not in features:
|
|
204
211
|
features.append('label')
|
|
205
212
|
|
|
213
|
+
if label_path is not None:
|
|
214
|
+
label_names = [os.path.split(lbl)[-1] for lbl in label_path]
|
|
206
215
|
|
|
207
216
|
|
|
208
217
|
features_log=f'features: {features}'
|
|
@@ -228,7 +237,10 @@ def measure_index(indices):
|
|
|
228
237
|
img = load_frames(img_num_channels[:,t], file, scale=None, normalize_input=False)
|
|
229
238
|
|
|
230
239
|
if label_path is not None:
|
|
231
|
-
|
|
240
|
+
|
|
241
|
+
lbl = locate_labels(pos, population=mode, frames=t)
|
|
242
|
+
if lbl is None:
|
|
243
|
+
continue
|
|
232
244
|
|
|
233
245
|
if trajectories is not None:
|
|
234
246
|
|
|
@@ -286,16 +298,16 @@ for th in threads:
|
|
|
286
298
|
|
|
287
299
|
|
|
288
300
|
if len(timestep_dataframes)>0:
|
|
301
|
+
|
|
289
302
|
df = pd.concat(timestep_dataframes)
|
|
290
|
-
df.reset_index(inplace=True, drop=True)
|
|
291
303
|
|
|
292
|
-
if trajectories is None:
|
|
304
|
+
if trajectories is not None:
|
|
305
|
+
df = df.sort_values(by=[column_labels['track'],column_labels['time']])
|
|
306
|
+
df = df.dropna(subset=[column_labels['track']])
|
|
307
|
+
else:
|
|
293
308
|
df['ID'] = np.arange(len(df))
|
|
294
309
|
|
|
295
|
-
|
|
296
|
-
df = df.sort_values(by=[column_labels['track'], column_labels['time']])
|
|
297
|
-
else:
|
|
298
|
-
df = df.sort_values(by=column_labels['time'])
|
|
310
|
+
df = df.reset_index(drop=True)
|
|
299
311
|
|
|
300
312
|
df.to_csv(pos+os.sep.join(["output", "tables", table_name]), index=False)
|
|
301
313
|
print(f'Measurements successfully written in table {pos+os.sep.join(["output", "tables", table_name])}')
|