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.
Files changed (41) hide show
  1. celldetective/__main__.py +30 -4
  2. celldetective/_version.py +1 -1
  3. celldetective/extra_properties.py +21 -0
  4. celldetective/filters.py +15 -2
  5. celldetective/gui/InitWindow.py +28 -34
  6. celldetective/gui/analyze_block.py +3 -498
  7. celldetective/gui/classifier_widget.py +1 -1
  8. celldetective/gui/control_panel.py +100 -29
  9. celldetective/gui/generic_signal_plot.py +35 -18
  10. celldetective/gui/gui_utils.py +143 -2
  11. celldetective/gui/layouts.py +7 -6
  12. celldetective/gui/measurement_options.py +38 -43
  13. celldetective/gui/plot_measurements.py +5 -13
  14. celldetective/gui/plot_signals_ui.py +30 -30
  15. celldetective/gui/process_block.py +66 -197
  16. celldetective/gui/retrain_segmentation_model_options.py +3 -1
  17. celldetective/gui/signal_annotator.py +50 -32
  18. celldetective/gui/signal_annotator2.py +7 -4
  19. celldetective/gui/styles.py +13 -0
  20. celldetective/gui/survival_ui.py +8 -21
  21. celldetective/gui/tableUI.py +1 -2
  22. celldetective/gui/thresholds_gui.py +195 -205
  23. celldetective/gui/viewers.py +262 -12
  24. celldetective/io.py +85 -11
  25. celldetective/measure.py +128 -88
  26. celldetective/models/segmentation_effectors/ricm_bf_all_last/config_input.json +79 -0
  27. celldetective/models/segmentation_effectors/ricm_bf_all_last/ricm_bf_all_last +0 -0
  28. celldetective/models/segmentation_effectors/ricm_bf_all_last/training_instructions.json +37 -0
  29. celldetective/models/segmentation_effectors/test-transfer/config_input.json +39 -0
  30. celldetective/models/segmentation_effectors/test-transfer/test-transfer +0 -0
  31. celldetective/neighborhood.py +0 -2
  32. celldetective/scripts/measure_cells.py +21 -9
  33. celldetective/signals.py +77 -66
  34. celldetective/tracking.py +19 -13
  35. {celldetective-1.3.2.dist-info → celldetective-1.3.4.dist-info}/METADATA +12 -10
  36. {celldetective-1.3.2.dist-info → celldetective-1.3.4.dist-info}/RECORD +41 -36
  37. {celldetective-1.3.2.dist-info → celldetective-1.3.4.dist-info}/WHEEL +1 -1
  38. tests/test_qt.py +5 -3
  39. {celldetective-1.3.2.dist-info → celldetective-1.3.4.dist-info}/LICENSE +0 -0
  40. {celldetective-1.3.2.dist-info → celldetective-1.3.4.dist-info}/entry_points.txt +0 -0
  41. {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
- blobs = blob_detection(img[:, :, ind], label, diameter=spot_detection['diameter'],
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
- df_props = df_props.merge(df_spots, how='outer', on='label')
366
- df_props['spot_count'] = df_props['spot_count'].replace(np.nan, 0).infer_objects(copy=False)
367
- df_props['spot_mean_intensity'] = df_props['spot_mean_intensity'].replace(np.nan, 0).infer_objects(copy=False)
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
- # print(intensity_features)
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
- df_props = df_props.merge(df_haralick, left_on='label',right_on='cell_id')
443
- #df_props = df_props.drop(columns=['cell_label'])
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 blob_detection(image, label, threshold, diameter):
920
- """
921
- Perform blob detection on an image based on labeled regions.
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
- Parameters:
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
- Returns:
930
- - dict: A dictionary containing information about detected blobs.
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
- This function performs blob detection on an image based on labeled regions. It iterates over each labeled region
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
- Note:
947
- - Blobs are detected using the Difference of Gaussians (DoG) method.
948
- - Detected blobs are filtered based on the specified threshold and expected diameter.
949
- - The returned dictionary contains information about the number of detected blobs and their mean intensity
950
- for each labeled region.
951
- """
952
- blob_labels = {}
953
- dilated_image = ndimage.grey_dilation(label, footprint=disk(10))
954
- for mask_index in np.unique(label):
955
- if mask_index == 0:
956
- continue
957
- removed_background = image.copy()
958
- one_mask = label.copy()
959
- one_mask[np.where(label != mask_index)] = 0
960
- dilated_copy = dilated_image.copy()
961
- dilated_copy[np.where(dilated_image != mask_index)] = 0
962
- removed_background[np.where(dilated_copy == 0)] = 0
963
- min_sigma = (1 / (1 + math.sqrt(2))) * diameter
964
- max_sigma = math.sqrt(2) * min_sigma
965
- blobs = skimage.feature.blob_dog(removed_background, threshold=threshold, min_sigma=min_sigma,
966
- max_sigma=max_sigma)
967
-
968
- mask = np.array([one_mask[int(y), int(x)] != 0 for y, x, r in blobs])
969
- if not np.any(mask):
970
- continue
971
- blobs_filtered = blobs[mask]
972
- binary_blobs = np.zeros_like(label)
973
- for blob in blobs_filtered:
974
- y, x, r = blob
975
- rr, cc = dsk((y, x), r, shape=binary_blobs.shape)
976
- binary_blobs[rr, cc] = 1
977
- spot_intensity = regionprops_table(binary_blobs, removed_background, ['intensity_mean'])
978
- blob_labels[mask_index] = [blobs_filtered.shape[0], spot_intensity['intensity_mean'][0]]
979
- return blob_labels
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
+ }
@@ -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
- lbl = imread(label_path[t])
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
- if column_labels['track'] in df.columns:
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])}')