celldetective 1.2.0__tar.gz → 1.2.1__tar.gz

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 (97) hide show
  1. {celldetective-1.2.0 → celldetective-1.2.1}/PKG-INFO +1 -1
  2. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/classifier_widget.py +7 -2
  3. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/neighborhood_options.py +3 -1
  4. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/signal_annotator.py +4 -4
  5. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/signal_annotator2.py +4 -4
  6. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/tableUI.py +4 -38
  7. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/io.py +2 -2
  8. celldetective-1.2.1/celldetective/models/segmentation_effectors/ricm-bimodal/config_input.json +130 -0
  9. celldetective-1.2.1/celldetective/models/segmentation_effectors/ricm-bimodal/ricm-bimodal +0 -0
  10. celldetective-1.2.1/celldetective/models/segmentation_effectors/ricm-bimodal/training_instructions.json +37 -0
  11. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/neighborhood.py +2 -0
  12. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/signals.py +3 -0
  13. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/utils.py +85 -17
  14. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective.egg-info/PKG-INFO +1 -1
  15. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective.egg-info/SOURCES.txt +3 -0
  16. {celldetective-1.2.0 → celldetective-1.2.1}/setup.py +1 -1
  17. {celldetective-1.2.0 → celldetective-1.2.1}/LICENSE +0 -0
  18. {celldetective-1.2.0 → celldetective-1.2.1}/README.md +0 -0
  19. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/__init__.py +0 -0
  20. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/__main__.py +0 -0
  21. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/datasets/segmentation_annotations/blank +0 -0
  22. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/datasets/signal_annotations/blank +0 -0
  23. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/events.py +0 -0
  24. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/extra_properties.py +0 -0
  25. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/filters.py +0 -0
  26. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/__init__.py +0 -0
  27. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/about.py +0 -0
  28. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/analyze_block.py +0 -0
  29. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/btrack_options.py +0 -0
  30. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/configure_new_exp.py +0 -0
  31. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/control_panel.py +0 -0
  32. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/gui_utils.py +0 -0
  33. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/json_readers.py +0 -0
  34. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/layouts.py +0 -0
  35. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/measurement_options.py +0 -0
  36. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/plot_measurements.py +0 -0
  37. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/plot_signals_ui.py +0 -0
  38. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/process_block.py +0 -0
  39. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/retrain_segmentation_model_options.py +0 -0
  40. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/retrain_signal_model_options.py +0 -0
  41. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/seg_model_loader.py +0 -0
  42. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/signal_annotator_options.py +0 -0
  43. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/styles.py +0 -0
  44. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/survival_ui.py +0 -0
  45. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/thresholds_gui.py +0 -0
  46. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/gui/viewers.py +0 -0
  47. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/icons/logo-large.png +0 -0
  48. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/icons/logo.png +0 -0
  49. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/icons/signals_icon.png +0 -0
  50. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/icons/splash-test.png +0 -0
  51. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/icons/splash.png +0 -0
  52. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/icons/splash0.png +0 -0
  53. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/icons/survival2.png +0 -0
  54. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/icons/vignette_signals2.png +0 -0
  55. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/icons/vignette_signals2.svg +0 -0
  56. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/links/zenodo.json +0 -0
  57. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/measure.py +0 -0
  58. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/models/pair_signal_detection/blank +0 -0
  59. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/models/segmentation_effectors/blank +0 -0
  60. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/models/segmentation_effectors/primNK_cfse/config_input.json +0 -0
  61. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/models/segmentation_effectors/primNK_cfse/cp-cfse-transfer +0 -0
  62. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/models/segmentation_effectors/primNK_cfse/training_instructions.json +0 -0
  63. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/models/segmentation_generic/blank +0 -0
  64. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/models/segmentation_targets/blank +0 -0
  65. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/models/signal_detection/blank +0 -0
  66. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/models/tracking_configs/mcf7.json +0 -0
  67. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/models/tracking_configs/ricm.json +0 -0
  68. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/models/tracking_configs/ricm2.json +0 -0
  69. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/preprocessing.py +0 -0
  70. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/relative_measurements.py +0 -0
  71. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/scripts/analyze_signals.py +0 -0
  72. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/scripts/measure_cells.py +0 -0
  73. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/scripts/measure_relative.py +0 -0
  74. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/scripts/segment_cells.py +0 -0
  75. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/scripts/segment_cells_thresholds.py +0 -0
  76. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/scripts/track_cells.py +0 -0
  77. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/scripts/train_segmentation_model.py +0 -0
  78. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/scripts/train_signal_model.py +0 -0
  79. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/segmentation.py +0 -0
  80. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective/tracking.py +0 -0
  81. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective.egg-info/dependency_links.txt +0 -0
  82. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective.egg-info/entry_points.txt +0 -0
  83. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective.egg-info/not-zip-safe +0 -0
  84. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective.egg-info/requires.txt +0 -0
  85. {celldetective-1.2.0 → celldetective-1.2.1}/celldetective.egg-info/top_level.txt +0 -0
  86. {celldetective-1.2.0 → celldetective-1.2.1}/setup.cfg +0 -0
  87. {celldetective-1.2.0 → celldetective-1.2.1}/tests/__init__.py +0 -0
  88. {celldetective-1.2.0 → celldetective-1.2.1}/tests/test_events.py +0 -0
  89. {celldetective-1.2.0 → celldetective-1.2.1}/tests/test_filters.py +0 -0
  90. {celldetective-1.2.0 → celldetective-1.2.1}/tests/test_io.py +0 -0
  91. {celldetective-1.2.0 → celldetective-1.2.1}/tests/test_measure.py +0 -0
  92. {celldetective-1.2.0 → celldetective-1.2.1}/tests/test_neighborhood.py +0 -0
  93. {celldetective-1.2.0 → celldetective-1.2.1}/tests/test_preprocessing.py +0 -0
  94. {celldetective-1.2.0 → celldetective-1.2.1}/tests/test_segmentation.py +0 -0
  95. {celldetective-1.2.0 → celldetective-1.2.1}/tests/test_signals.py +0 -0
  96. {celldetective-1.2.0 → celldetective-1.2.1}/tests/test_tracking.py +0 -0
  97. {celldetective-1.2.0 → celldetective-1.2.1}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: celldetective
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: description
5
5
  Home-page: http://github.com/remyeltorro/celldetective
6
6
  Author: Rémy Torro
@@ -279,9 +279,12 @@ class ClassifierWidget(QWidget, Styles):
279
279
  try:
280
280
  if cols_in_df:
281
281
  self.selection = self.df.dropna(subset=cols).query(query).index
282
+ null_selection = self.df[self.df.loc[:,cols].isna().any(axis=1)].index
283
+ self.df.loc[null_selection, self.class_name] = np.nan
284
+ self.df.loc[self.selection, self.class_name] = 0
282
285
  else:
283
- self.selection = self.df.query(query).index
284
- self.df.loc[self.selection, self.class_name] = 0
286
+ self.df.loc[:, self.class_name] = np.nan
287
+
285
288
  except Exception as e:
286
289
  print(e)
287
290
  print(self.df.columns)
@@ -384,6 +387,7 @@ class ClassifierWidget(QWidget, Styles):
384
387
  self.df.loc[indices, self.class_name_user] = 2
385
388
  self.df.loc[indices, self.class_name_user.replace('class','t')] = -1
386
389
  if self.irreversible_event_btn.isChecked():
390
+ self.df.loc[self.df[self.class_name_user]!=2, self.class_name_user.replace('class', 't')] = -1
387
391
  self.estimate_time()
388
392
  else:
389
393
  self.group_name_user = 'group_' + self.name_le.text()
@@ -415,6 +419,7 @@ class ClassifierWidget(QWidget, Styles):
415
419
  # reset
416
420
  #self.init_class()
417
421
  #self.update_props_scatter()
422
+ self.parent_window.parent_window.update_position_options()
418
423
  self.close()
419
424
 
420
425
  def switch_to_log(self, i):
@@ -230,11 +230,12 @@ class ConfigNeighborhoods(QWidget, Styles):
230
230
 
231
231
  status_layout = QHBoxLayout()
232
232
 
233
- status_layout.addWidget(QLabel('status: '), 30)
233
+ #status_layout.addWidget(QLabel('status: '), 30)
234
234
 
235
235
  status_sublayout = QHBoxLayout()
236
236
  self.reference_population_status_cb = QComboBox()
237
237
  self.reference_population_status_cb.setToolTip('Status of the reference population.')
238
+ self.reference_population_status_cb.hide()
238
239
  status_sublayout.addWidget(self.reference_population_status_cb,95)
239
240
 
240
241
  self.reference_switch_status_btn = QPushButton("")
@@ -243,6 +244,7 @@ class ConfigNeighborhoods(QWidget, Styles):
243
244
  self.reference_switch_status_btn.setIconSize(QSize(20, 20))
244
245
  self.reference_switch_status_btn.clicked.connect(self.switch_not_reference)
245
246
  self.reference_switch_status_btn.setToolTip('Invert status values.')
247
+ self.reference_switch_status_btn.hide()
246
248
 
247
249
  status_sublayout.addWidget(self.reference_switch_status_btn, 5)
248
250
 
@@ -1361,10 +1361,10 @@ class MeasureAnnotator(SignalAnnotator):
1361
1361
  self.locate_stack()
1362
1362
 
1363
1363
  data, properties, graph, labels, _ = load_napari_data(self.pos, prefix=None, population=self.mode,return_stack=False)
1364
- if data is not None:
1365
- self.labels = relabel_segmentation(labels,data,properties)
1366
- else:
1367
- self.labels = labels
1364
+ # if data is not None:
1365
+ # self.labels = relabel_segmentation(labels,data,properties)
1366
+ # else:
1367
+ self.labels = labels
1368
1368
 
1369
1369
  self.current_channel = 0
1370
1370
 
@@ -1869,15 +1869,15 @@ class SignalAnnotator2(QMainWindow,Styles):
1869
1869
 
1870
1870
 
1871
1871
  if self.df_targets is not None:
1872
- self.target_status_scatter = self.ax.scatter(self.target_positions[0][:,0], self.target_positions[0][:,1], marker="x", c=self.target_colors[0][:,1], s=50, picker=True, pickradius=10)
1873
- self.target_class_scatter = self.ax.scatter(self.target_positions[0][:,0], self.target_positions[0][:,1], marker='o', facecolors='none',edgecolors=self.target_colors[0][:,0], s=200)
1872
+ self.target_status_scatter = self.ax.scatter(self.target_positions[0][:,0], self.target_positions[0][:,1], marker="x", c=self.target_colors[0][:,1], s=50, picker=True, pickradius=10, zorder=10)
1873
+ self.target_class_scatter = self.ax.scatter(self.target_positions[0][:,0], self.target_positions[0][:,1], marker='o', facecolors='none',edgecolors=self.target_colors[0][:,0], s=200, zorder=10)
1874
1874
  else:
1875
1875
  self.target_status_scatter = self.ax.scatter([],[], marker="x", s=50, picker=True, pickradius=10)
1876
1876
  self.target_class_scatter = self.ax.scatter([],[], marker='o', facecolors='none', s=200)
1877
1877
 
1878
1878
  if self.df_effectors is not None:
1879
- self.effector_status_scatter = self.ax.scatter(self.effector_positions[0][:,0], self.effector_positions[0][:,1], marker="x", c=self.effector_colors[0][:,1], s=50, picker=True, pickradius=10)
1880
- self.effector_class_scatter = self.ax.scatter(self.effector_positions[0][:,0], self.effector_positions[0][:,1], marker='^', facecolors='none',edgecolors=self.effector_colors[0][:,0], s=200)
1879
+ self.effector_status_scatter = self.ax.scatter(self.effector_positions[0][:,0], self.effector_positions[0][:,1], marker="x", c=self.effector_colors[0][:,1], s=50, picker=True, pickradius=10, zorder=10)
1880
+ self.effector_class_scatter = self.ax.scatter(self.effector_positions[0][:,0], self.effector_positions[0][:,1], marker='^', facecolors='none',edgecolors=self.effector_colors[0][:,0], s=200, zorder=10)
1881
1881
  else:
1882
1882
  self.effector_status_scatter = self.ax.scatter([], [], marker="x", s=50, picker=True, pickradius=10)
1883
1883
  self.effector_class_scatter = self.ax.scatter([],[], marker='^', facecolors='none', s=200)
@@ -5,7 +5,7 @@ import matplotlib.pyplot as plt
5
5
  from matplotlib.cm import viridis
6
6
  plt.rcParams['svg.fonttype'] = 'none'
7
7
  from celldetective.gui.gui_utils import FigureCanvas, center_window
8
- from celldetective.utils import differentiate_per_track
8
+ from celldetective.utils import differentiate_per_track, collapse_trajectories_by_status
9
9
  import numpy as np
10
10
  import seaborn as sns
11
11
  import matplotlib.cm as mcm
@@ -335,7 +335,7 @@ class TableUI(QMainWindow, Styles):
335
335
  self.tracks = False
336
336
 
337
337
  if self.population=='pairs':
338
- self.groupby_cols = ['position','reference_population', 'neighbor_population','REFERENCE_ID', 'NEIGHBOR_ID', 'FRAME']
338
+ self.groupby_cols = ['position','reference_population', 'neighbor_population','REFERENCE_ID', 'NEIGHBOR_ID']
339
339
  self.tracks = True # for now
340
340
  else:
341
341
  if 'TRACK_ID' in data.columns:
@@ -959,7 +959,7 @@ class TableUI(QMainWindow, Styles):
959
959
  pass
960
960
 
961
961
  if self.population=='pairs':
962
- for col in self.groupby_cols[1:]: #['neighbor_population', 'reference_population', 'NEIGHBOR_ID', 'REFERENCE_ID']
962
+ for col in reversed(self.groupby_cols): #['neighbor_population', 'reference_population', 'NEIGHBOR_ID', 'REFERENCE_ID']
963
963
  if col in group_table:
964
964
  first_column = group_table.pop(col)
965
965
  group_table.insert(0, col, first_column)
@@ -1005,41 +1005,7 @@ class TableUI(QMainWindow, Styles):
1005
1005
 
1006
1006
  elif self.per_status_option.isChecked():
1007
1007
 
1008
- status_of_interest = self.per_status_cb.currentText()
1009
- self.projection_mode = f'{self.status_operation.currentText()} per {status_of_interest}'
1010
- self.data = self.data.dropna(subset=status_of_interest,ignore_index=True)
1011
- unique_statuses = np.unique(self.data[status_of_interest].to_numpy())
1012
-
1013
- df_sections = []
1014
- for s in unique_statuses:
1015
- subtab = self.data.loc[self.data[status_of_interest]==s,:]
1016
- op = getattr(subtab.groupby(self.groupby_cols), self.status_operation.currentText())
1017
- subtab_projected = op(subtab.groupby(self.groupby_cols))
1018
- frame_duration = subtab.groupby(self.groupby_cols).size().to_numpy()
1019
- for c in self.static_columns:
1020
- try:
1021
- subtab_projected[c] = subtab.groupby(self.groupby_cols)[c].apply(lambda x: x.unique()[0])
1022
- except Exception as e:
1023
- print(e)
1024
- pass
1025
- subtab_projected['duration_in_state'] = frame_duration
1026
- df_sections.append(subtab_projected)
1027
-
1028
- group_table = pd.concat(df_sections,axis=0,ignore_index=True)
1029
-
1030
- if self.population=='pairs':
1031
- for col in ['duration_in_state',status_of_interest, 'neighbor_population', 'reference_population', 'NEIGHBOR_ID', 'REFERENCE_ID']:
1032
- first_column = group_table.pop(col)
1033
- group_table.insert(0, col, first_column)
1034
- else:
1035
- for col in ['duration_in_state',status_of_interest,'TRACK_ID']:
1036
- first_column = group_table.pop(col)
1037
- group_table.insert(0, col, first_column)
1038
-
1039
- group_table.pop('FRAME')
1040
- group_table = group_table.sort_values(by=self.groupby_cols + [status_of_interest],ignore_index=True)
1041
- group_table = group_table.reset_index(drop=True)
1042
-
1008
+ group_table = collapse_trajectories_by_status(self.data, status=self.per_status_cb.currentText(),population=self.population, projection=self.status_operation.currentText(), groupby_columns=self.groupby_cols)
1043
1009
 
1044
1010
  self.subtable = TableUI(group_table,f"Group by tracks: {self.projection_mode}", plot_mode="static")
1045
1011
  self.subtable.show()
@@ -628,7 +628,7 @@ def locate_stack(position, prefix='Aligned'):
628
628
 
629
629
  stack_path = glob(position + os.sep.join(['movie', f'{prefix}*.tif']))
630
630
  assert len(stack_path) > 0, f"No movie with prefix {prefix} found..."
631
- stack = imread(stack_path[0].replace('\\', '/'), is_mmstack=False)
631
+ stack = imread(stack_path[0].replace('\\', '/'))
632
632
  if stack.ndim == 4:
633
633
  stack = np.moveaxis(stack, 1, -1)
634
634
  elif stack.ndim == 3:
@@ -1616,7 +1616,7 @@ def correct_annotation(filename):
1616
1616
  def save_widget():
1617
1617
  return export_labels()
1618
1618
 
1619
- img = imread(filename.replace('\\','/'),is_mmstack=False)
1619
+ img = imread(filename.replace('\\','/'))
1620
1620
  if img.ndim==3:
1621
1621
  img = np.moveaxis(img, 0, -1)
1622
1622
  elif img.ndim==2:
@@ -0,0 +1,130 @@
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/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_100_0109.tif",
32
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/StaticRICM-Dom-20191016-Her2-10nM-C7b21_200_0057.tif",
33
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/StaticRICM-Dom-20191016-Her2-10nM-C7b21_200_0058.tif",
34
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/AdhesionDalia-26-08_209_0022.tif",
35
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/AdhesionDalia-26-08_2015_0039.tif",
36
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Exp20190619_700_0024.tif",
37
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia-2021-04-27_C7b21NF-incub-with-cells-test_605_0037.tif",
38
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_102_0039.tif",
39
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_200_0034.tif",
40
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_103_0011.tif",
41
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_701_0004.tif",
42
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_201_0035.tif",
43
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_100_0016.tif",
44
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia-2021-04-27_C7b21NF-incub-with-cells-test_202_0020.tif",
45
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dominique20191016_303_0016.tif",
46
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_502_0000.tif",
47
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/20231213_RICM_2C11_PP2_normed_201_0000.tif",
48
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_105_0031.tif",
49
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/AdhesionDalia-26-08_2012_0039.tif",
50
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia-2021-04-27_C7b21NF-incub-with-cells-test_608_0028.tif",
51
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_2012_0027.tif",
52
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_101_0021.tif",
53
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia-2021-04-27_C7b21NF-incub-with-cells-test_302_0039.tif",
54
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_104_0036.tif",
55
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_801_0036.tif",
56
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_502_0036.tif",
57
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_808_0173.tif",
58
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_5011_0006.tif",
59
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/StaticRICM-Dom-20191016-Her2-10nM-C7b21_800_0019.tif",
60
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dominique20191016_302_0039.tif",
61
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Exp20190619_400_0061.tif",
62
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/20231213_RICM_2C11_PP2_normed_106_0117.tif",
63
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_402_0039.tif",
64
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/20231213_RICM_2C11_PP2_normed_305_0158.tif",
65
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/20231213_RICM_2C11_PP2_normed_308_0191.tif",
66
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/StaticRICM-Dom-20191016-Her2-10nM-C7b21_800_0050.tif",
67
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_500_0127.tif",
68
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/20231213_RICM_2C11_PP2_normed_300_0009.tif",
69
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_701_0082.tif",
70
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/StaticRICM-Dom-20191016-Her2-10nM-C7b21_800_0000.tif",
71
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_303_0019.tif",
72
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/StaticRICM-Dom-20191016-Her2-10nM-C7b21_800_0002.tif",
73
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Exp20190619_700_0009.tif",
74
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_701_0055.tif",
75
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_104_0019.tif",
76
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/20231213_RICM_2C11_PP2_normed_600_0108.tif",
77
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/StaticRICM-Dom-20191016-Her2-10nM-C7b21_800_0021.tif",
78
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/20231213_RICM_2C11_PP2_normed_600_0193_roi_491_996_143_708.tif",
79
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/20231213_RICM_2C11_PP2_normed_106_0000.tif",
80
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_2014_0038.tif",
81
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia-2021-04-27_C7b21NF-incub-with-cells-test_604_0033.tif",
82
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_303_0025.tif",
83
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_105_0038.tif",
84
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia-2021-04-27_C7b21NF-incub-with-cells-test_201_0039.tif",
85
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/20231213_RICM_2C11_PP2_normed_406_0202.tif",
86
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_105_0028.tif",
87
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_600_0172.tif",
88
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/20231213_RICM_2C11_PP2_normed_600_0193.tif",
89
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_3011_0036.tif",
90
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_203_0024.tif",
91
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_209_0020.tif",
92
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/20231213_RICM_2C11_PP2_normed_100_0181.tif",
93
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_201_0034.tif",
94
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_704_0010.tif",
95
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_2014_0034.tif",
96
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_303_0021.tif",
97
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Exp20190619_700_0023.tif",
98
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_600_0019.tif",
99
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_808_0016.tif",
100
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dominique20191016_303_0039.tif",
101
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_103_0034.tif",
102
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_101_0038.tif",
103
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_100_0007.tif",
104
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia-2021-04-27_C7b21NF-incub-with-cells-test_607_0035.tif",
105
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_200_0006.tif",
106
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_206_0030.tif"
107
+ ],
108
+ "validation": [
109
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia-2021-04-27_C7b21NF-incub-with-cells-test_6011_0026.tif",
110
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_100_0035.tif",
111
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/AdhesionDalia-26-08_208_0020.tif",
112
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_102_0031.tif",
113
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia-2021-04-27_C7b21NF-incub-with-cells-test_200_0039.tif",
114
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_502_0150.tif",
115
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dominique20191016_304_0033.tif",
116
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_1015_0036.tif",
117
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/StaticRICM-Dom-20191016-Her2-10nM-C7b21_200_0061.tif",
118
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_5013_0000.tif",
119
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Exp20190619_700_0025.tif",
120
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia08052020_105_0039.tif",
121
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Marie_801_0177.tif",
122
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_504_0016.tif",
123
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dominique20191016_301_0039.tif",
124
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia01092020_504_0037.tif",
125
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dominique20191016_305_0030.tif",
126
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/Dalia-2021-04-27_C7b21NF-incub-with-cells-test_606_0036.tif",
127
+ "/home/kheya/Documents/torro-cinam/DATASET-RICM/combined/20231213_RICM_2C11_PP2_normed_300_0087.tif"
128
+ ]
129
+ }
130
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "model_name": "ricm-bimodal",
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/kheya/Documents/torro-cinam/DATASET-RICM/combined"
30
+ ],
31
+ "augmentation_factor": 3.0,
32
+ "validation_split": 0.2,
33
+ "learning_rate": 0.008,
34
+ "batch_size": 16,
35
+ "epochs": 3000,
36
+ "target_directory": "/home/kheya/Documents/torro-cinam/GitHub/celldetective/celldetective/models/segmentation_effectors"
37
+ }
@@ -387,6 +387,8 @@ def compute_neighborhood_at_position(pos, distance, population=['targets', 'effe
387
387
 
388
388
  df_A, path_A = get_position_table(pos, population=population[0], return_path=True)
389
389
  df_B, path_B = get_position_table(pos, population=population[1], return_path=True)
390
+ if df_A is None or df_B is None:
391
+ return None
390
392
 
391
393
  if clear_neigh:
392
394
  if os.path.exists(path_A.replace('.csv','.pkl')):
@@ -155,6 +155,7 @@ def analyze_signals(trajectories, model, interpolate_na=True,
155
155
  f = open(model_config_path)
156
156
  config = json.load(f)
157
157
  required_signals = config["channels"]
158
+ model_signal_length = config['model_signal_length']
158
159
 
159
160
  try:
160
161
  label = config['label']
@@ -190,6 +191,8 @@ def analyze_signals(trajectories, model, interpolate_na=True,
190
191
  trajectories_clean = clean_trajectories(trajectories, interpolate_na=interpolate_na, interpolate_position_gaps=interpolate_na, column_labels=column_labels)
191
192
 
192
193
  max_signal_size = int(trajectories_clean[column_labels['time']].max()) + 2
194
+ assert max_signal_size <= model_signal_length,f'The current signals are longer ({max_signal_size}) than the maximum expected input ({model_signal_length}) for this signal analysis model. Abort...'
195
+
193
196
  tracks = trajectories_clean[column_labels['track']].unique()
194
197
  signals = np.zeros((len(tracks),max_signal_size, len(selected_signals)))
195
198
 
@@ -1289,16 +1289,27 @@ def _extract_channel_indices_from_config(config, channels_to_extract):
1289
1289
  # V2
1290
1290
  channels = []
1291
1291
  for c in channels_to_extract:
1292
- if c!='None' and c is not None:
1293
- try:
1294
- c1 = int(ConfigSectionMap(config,"Channels")[c])
1295
- channels.append(c1)
1296
- except Exception as e:
1297
- print(f"Error {e}. The channel required by the model is not available in your data... Check the configuration file.")
1298
- channels = None
1299
- break
1300
- else:
1292
+ try:
1293
+ c1 = int(ConfigSectionMap(config,"Channels")[c])
1294
+ channels.append(c1)
1295
+ except Exception as e:
1296
+ print(f"Warning... The channel {c} required by the model is not available in your data...")
1301
1297
  channels.append(None)
1298
+ if np.all([c is None for c in channels]):
1299
+ channels = None
1300
+
1301
+ # channels = []
1302
+ # for c in channels_to_extract:
1303
+ # if c!='None' and c is not None:
1304
+ # try:
1305
+ # c1 = int(ConfigSectionMap(config,"Channels")[c])
1306
+ # channels.append(c1)
1307
+ # except Exception as e:
1308
+ # print(f"Error {e}. The channel required by the model is not available in your data... Check the configuration file.")
1309
+ # channels = None
1310
+ # break
1311
+ # else:
1312
+ # channels.append(None)
1302
1313
 
1303
1314
  # LEGACY
1304
1315
  if channels is None:
@@ -2164,6 +2175,8 @@ def load_image_dataset(datasets, channels, train_spatial_calibration=None, mask_
2164
2175
  - Spatial calibration adjustment involves rescaling the images and masks to match the `train_spatial_calibration`.
2165
2176
  - Only images with a corresponding mask and a valid configuration file specifying channel indices and
2166
2177
  spatial calibration are loaded.
2178
+ - The image samples must have at least one channel in common with the required channels to be accepted. The missing
2179
+ channels are passed as black frames.
2167
2180
 
2168
2181
  Examples
2169
2182
  --------
@@ -2202,24 +2215,29 @@ def load_image_dataset(datasets, channels, train_spatial_calibration=None, mask_
2202
2215
  # Load config
2203
2216
  with open(config_path, 'r') as f:
2204
2217
  config = json.load(f)
2205
- try:
2218
+
2219
+ existing_channels = config['channels']
2220
+ intersection = list(set(list(channels)) & set(list(existing_channels)))
2221
+ print(f'{existing_channels=} {intersection=}')
2222
+ if len(intersection)==0:
2223
+ print(e,' channels could not be found in the config... Skipping image.')
2224
+ continue
2225
+ else:
2206
2226
  ch_idx = []
2207
2227
  for c in channels:
2208
- if c!='None':
2209
- idx = config['channels'].index(c)
2228
+ if c in existing_channels:
2229
+ idx = existing_channels.index(c)
2210
2230
  ch_idx.append(idx)
2211
2231
  else:
2232
+ # For None or missing channel pass black frame
2212
2233
  ch_idx.append(np.nan)
2213
2234
  im_calib = config['spatial_calibration']
2214
- except Exception as e:
2215
- print(e,' channels and/or spatial calibration could not be found in the config... Skipping image.')
2216
- continue
2217
2235
 
2218
2236
  ch_idx = np.array(ch_idx)
2219
2237
  ch_idx_safe = np.copy(ch_idx)
2220
2238
  ch_idx_safe[ch_idx_safe!=ch_idx_safe] = 0
2221
2239
  ch_idx_safe = ch_idx_safe.astype(int)
2222
- print(ch_idx_safe)
2240
+
2223
2241
  image = image[ch_idx_safe]
2224
2242
  image[np.where(ch_idx!=ch_idx)[0],:,:] = 0
2225
2243
 
@@ -2233,6 +2251,14 @@ def load_image_dataset(datasets, channels, train_spatial_calibration=None, mask_
2233
2251
 
2234
2252
  X.append(image)
2235
2253
  Y.append(mask)
2254
+
2255
+ # fig,ax = plt.subplots(1,image.shape[-1]+1)
2256
+ # for k in range(image.shape[-1]):
2257
+ # ax[k].imshow(image[:,:,k],cmap='gray')
2258
+ # ax[image.shape[-1]].imshow(mask)
2259
+ # plt.pause(1)
2260
+ # plt.close()
2261
+
2236
2262
  files.append(im)
2237
2263
 
2238
2264
  assert len(X)==len(Y),'The number of images does not match with the number of masks... Abort.'
@@ -2367,4 +2393,46 @@ def interpolate_nan(img, method='nearest'):
2367
2393
  interp_grid = griddata(points, values, (x_grid, y_grid), method=method)
2368
2394
  return interp_grid
2369
2395
  else:
2370
- return img
2396
+ return img
2397
+
2398
+ def collapse_trajectories_by_status(df, status=None, projection='mean', population='effectors', groupby_columns=['position','TRACK_ID']):
2399
+
2400
+ static_columns = ['well_index', 'well_name', 'pos_name', 'position', 'well', 'status', 't0', 'class','cell_type','concentration', 'antibody', 'pharmaceutical_agent','TRACK_ID','position', 'neighbor_population', 'reference_population', 'NEIGHBOR_ID', 'REFERENCE_ID', 'FRAME']
2401
+
2402
+ if status is None or status not in list(df.columns):
2403
+ print('invalid status selection...')
2404
+ return None
2405
+
2406
+ df = df.dropna(subset=status,ignore_index=True)
2407
+ unique_statuses = np.unique(df[status].to_numpy())
2408
+
2409
+ df_sections = []
2410
+ for s in unique_statuses:
2411
+ subtab = df.loc[df[status]==s,:]
2412
+ op = getattr(subtab.groupby(groupby_columns), projection)
2413
+ subtab_projected = op(subtab.groupby(groupby_columns))
2414
+ frame_duration = subtab.groupby(groupby_columns).size().to_numpy()
2415
+ for c in static_columns:
2416
+ try:
2417
+ subtab_projected[c] = subtab.groupby(groupby_columns)[c].apply(lambda x: x.unique()[0])
2418
+ except Exception as e:
2419
+ print(e)
2420
+ pass
2421
+ subtab_projected['duration_in_state'] = frame_duration
2422
+ df_sections.append(subtab_projected)
2423
+
2424
+ group_table = pd.concat(df_sections,axis=0,ignore_index=True)
2425
+ if population=='pairs':
2426
+ for col in ['duration_in_state',status, 'neighbor_population', 'reference_population', 'NEIGHBOR_ID', 'REFERENCE_ID']:
2427
+ first_column = group_table.pop(col)
2428
+ group_table.insert(0, col, first_column)
2429
+ else:
2430
+ for col in ['duration_in_state',status,'TRACK_ID']:
2431
+ first_column = group_table.pop(col)
2432
+ group_table.insert(0, col, first_column)
2433
+
2434
+ group_table.pop('FRAME')
2435
+ group_table = group_table.sort_values(by=groupby_columns + [status],ignore_index=True)
2436
+ group_table = group_table.reset_index(drop=True)
2437
+
2438
+ return group_table
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: celldetective
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: description
5
5
  Home-page: http://github.com/remyeltorro/celldetective
6
6
  Author: Rémy Torro
@@ -65,6 +65,9 @@ celldetective/models/segmentation_effectors/blank
65
65
  celldetective/models/segmentation_effectors/primNK_cfse/config_input.json
66
66
  celldetective/models/segmentation_effectors/primNK_cfse/cp-cfse-transfer
67
67
  celldetective/models/segmentation_effectors/primNK_cfse/training_instructions.json
68
+ celldetective/models/segmentation_effectors/ricm-bimodal/config_input.json
69
+ celldetective/models/segmentation_effectors/ricm-bimodal/ricm-bimodal
70
+ celldetective/models/segmentation_effectors/ricm-bimodal/training_instructions.json
68
71
  celldetective/models/segmentation_generic/blank
69
72
  celldetective/models/segmentation_targets/blank
70
73
  celldetective/models/signal_detection/blank
@@ -18,7 +18,7 @@ except:
18
18
  requirements = [str(ir.requirement) for ir in requirements]
19
19
 
20
20
  setup(name='celldetective',
21
- version='1.2.0',
21
+ version='1.2.1',
22
22
  description='description',
23
23
  long_description=(this_directory / "README.md").read_text(),
24
24
  #long_description=open('README.rst',encoding="utf8").read(),
File without changes
File without changes
File without changes