celldetective 1.3.4.post1__py3-none-any.whl → 1.3.6.post1__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 (35) hide show
  1. celldetective/_version.py +1 -1
  2. celldetective/events.py +10 -5
  3. celldetective/filters.py +11 -0
  4. celldetective/gui/btrack_options.py +151 -1
  5. celldetective/gui/classifier_widget.py +44 -15
  6. celldetective/gui/configure_new_exp.py +13 -0
  7. celldetective/gui/control_panel.py +4 -2
  8. celldetective/gui/generic_signal_plot.py +2 -6
  9. celldetective/gui/gui_utils.py +170 -12
  10. celldetective/gui/measurement_options.py +85 -54
  11. celldetective/gui/neighborhood_options.py +1 -1
  12. celldetective/gui/plot_signals_ui.py +3 -4
  13. celldetective/gui/process_block.py +8 -6
  14. celldetective/gui/signal_annotator.py +10 -3
  15. celldetective/gui/signal_annotator2.py +146 -193
  16. celldetective/gui/survival_ui.py +121 -34
  17. celldetective/gui/tableUI.py +26 -12
  18. celldetective/gui/thresholds_gui.py +9 -52
  19. celldetective/gui/viewers.py +58 -21
  20. celldetective/io.py +1087 -161
  21. celldetective/measure.py +175 -102
  22. celldetective/preprocessing.py +2 -2
  23. celldetective/relative_measurements.py +6 -9
  24. celldetective/scripts/measure_cells.py +13 -3
  25. celldetective/scripts/segment_cells.py +0 -1
  26. celldetective/scripts/track_cells.py +25 -1
  27. celldetective/signals.py +9 -7
  28. celldetective/tracking.py +130 -81
  29. celldetective/utils.py +28 -7
  30. {celldetective-1.3.4.post1.dist-info → celldetective-1.3.6.post1.dist-info}/METADATA +3 -2
  31. {celldetective-1.3.4.post1.dist-info → celldetective-1.3.6.post1.dist-info}/RECORD +35 -35
  32. {celldetective-1.3.4.post1.dist-info → celldetective-1.3.6.post1.dist-info}/LICENSE +0 -0
  33. {celldetective-1.3.4.post1.dist-info → celldetective-1.3.6.post1.dist-info}/WHEEL +0 -0
  34. {celldetective-1.3.4.post1.dist-info → celldetective-1.3.6.post1.dist-info}/entry_points.txt +0 -0
  35. {celldetective-1.3.4.post1.dist-info → celldetective-1.3.6.post1.dist-info}/top_level.txt +0 -0
celldetective/tracking.py CHANGED
@@ -8,17 +8,18 @@ from btrack import BayesianTracker
8
8
 
9
9
  from celldetective.measure import measure_features
10
10
  from celldetective.utils import rename_intensity_column, velocity_per_track
11
- from celldetective.io import view_on_napari_btrack, interpret_tracking_configuration
11
+ from celldetective.io import interpret_tracking_configuration
12
12
 
13
13
  import os
14
14
  import subprocess
15
+ import trackpy as tp
15
16
 
16
17
  abs_path = os.sep.join([os.path.split(os.path.dirname(os.path.realpath(__file__)))[0],'celldetective'])
17
18
 
18
19
  def track(labels, configuration=None, stack=None, spatial_calibration=1, features=None, channel_names=None,
19
20
  haralick_options=None, return_napari_data=False, view_on_napari=False, mask_timepoints=None, mask_channels=None, volume=(2048,2048),
20
21
  optimizer_options = {'tm_lim': int(12e4)}, track_kwargs={'step_size': 100}, objects=None,
21
- clean_trajectories_kwargs=None, column_labels={'track': "TRACK_ID", 'time': 'FRAME', 'x': 'POSITION_X', 'y': 'POSITION_Y'},
22
+ clean_trajectories_kwargs=None, btrack_option=True, search_range=None, memory=None,column_labels={'track': "TRACK_ID", 'time': 'FRAME', 'x': 'POSITION_X', 'y': 'POSITION_Y'},
22
23
  ):
23
24
 
24
25
  """
@@ -90,6 +91,12 @@ def track(labels, configuration=None, stack=None, spatial_calibration=1, feature
90
91
  configuration = interpret_tracking_configuration(configuration)
91
92
 
92
93
  if objects is None:
94
+
95
+ if not btrack_option:
96
+ features = []
97
+ channel_names = None
98
+ haralick_options = None
99
+
93
100
  objects = extract_objects_and_features(labels, stack, features,
94
101
  channel_names=channel_names,
95
102
  haralick_options=haralick_options,
@@ -97,78 +104,100 @@ def track(labels, configuration=None, stack=None, spatial_calibration=1, feature
97
104
  mask_channels=mask_channels,
98
105
  )
99
106
 
100
- columns = list(objects.columns)
101
- to_remove = ['x','y','class_id','t']
102
- for tr in to_remove:
103
- try:
104
- columns.remove(tr)
105
- except:
106
- print(f'column {tr} could not be found...')
107
-
108
- scaler = StandardScaler()
109
- if columns:
110
- x = objects[columns].values
111
- x_scaled = scaler.fit_transform(x)
112
- df_temp = pd.DataFrame(x_scaled, columns=columns, index = objects.index)
113
- objects[columns] = df_temp
114
- else:
115
- print('Warning: no features were passed to bTrack...')
107
+ if btrack_option:
108
+ columns = list(objects.columns)
109
+ to_remove = ['x','y','class_id','t']
110
+ for tr in to_remove:
111
+ try:
112
+ columns.remove(tr)
113
+ except:
114
+ print(f'column {tr} could not be found...')
116
115
 
117
- # 2) track the objects
118
- new_btrack_objects = localizations_to_objects(objects)
116
+ scaler = StandardScaler()
117
+ if columns:
118
+ x = objects[columns].values
119
+ x_scaled = scaler.fit_transform(x)
120
+ df_temp = pd.DataFrame(x_scaled, columns=columns, index = objects.index)
121
+ objects[columns] = df_temp
122
+ else:
123
+ print('Warning: no features were passed to bTrack...')
119
124
 
120
- with BayesianTracker() as tracker:
125
+ # 2) track the objects
126
+ new_btrack_objects = localizations_to_objects(objects)
121
127
 
122
- tracker.configure(configuration)
128
+ with BayesianTracker() as tracker:
123
129
 
124
- if columns:
125
- tracking_updates = ["motion","visual"]
126
- #tracker.tracking_updates = ["motion","visual"]
127
- tracker.features = columns
130
+ tracker.configure(configuration)
131
+
132
+ if columns:
133
+ tracking_updates = ["motion","visual"]
134
+ #tracker.tracking_updates = ["motion","visual"]
135
+ tracker.features = columns
136
+ else:
137
+ tracking_updates = ["motion"]
138
+
139
+ tracker.append(new_btrack_objects)
140
+ tracker.volume = ((0,volume[0]), (0,volume[1]), (-1e5, 1e5)) #(-1e5, 1e5)
141
+ #print(tracker.volume)
142
+ tracker.track(tracking_updates=tracking_updates, **track_kwargs)
143
+ tracker.optimize(options=optimizer_options)
144
+
145
+ data, properties, graph = tracker.to_napari() #ndim=2
146
+ # do the table post processing and napari options
147
+ if data.shape[1]==4:
148
+ df = pd.DataFrame(data, columns=[column_labels['track'],column_labels['time'],column_labels['y'],column_labels['x']])
149
+ elif data.shape[1]==5:
150
+ df = pd.DataFrame(data, columns=[column_labels['track'],column_labels['time'],"z",column_labels['y'],column_labels['x']])
151
+ df = df.drop(columns=['z'])
152
+ df[column_labels['x']+'_um'] = df[column_labels['x']]*spatial_calibration
153
+ df[column_labels['y']+'_um'] = df[column_labels['y']]*spatial_calibration
154
+
155
+ else:
156
+ properties = None
157
+ graph = {}
158
+ print(f"{objects=} {objects.columns=}")
159
+ objects = objects.rename(columns={"t": "frame"})
160
+ if search_range is not None and memory is not None:
161
+ data = tp.link(objects, search_range, memory=memory,link_strategy='auto')
128
162
  else:
129
- tracking_updates = ["motion"]
130
-
131
- tracker.append(new_btrack_objects)
132
- tracker.volume = ((0,volume[0]), (0,volume[1]), (-1e5, 1e5)) #(-1e5, 1e5)
133
- #print(tracker.volume)
134
- tracker.track(tracking_updates=tracking_updates, **track_kwargs)
135
- tracker.optimize(options=optimizer_options)
136
-
137
- data, properties, graph = tracker.to_napari() #ndim=2
138
-
139
- # do the table post processing and napari options
140
- if data.shape[1]==4:
141
- df = pd.DataFrame(data, columns=[column_labels['track'],column_labels['time'],column_labels['y'],column_labels['x']])
142
- elif data.shape[1]==5:
143
- df = pd.DataFrame(data, columns=[column_labels['track'],column_labels['time'],"z",column_labels['y'],column_labels['x']])
144
- df = df.drop(columns=['z'])
145
- df[column_labels['x']+'_um'] = df[column_labels['x']]*spatial_calibration
146
- df[column_labels['y']+'_um'] = df[column_labels['y']]*spatial_calibration
147
-
148
- df = df.merge(pd.DataFrame(properties),left_index=True, right_index=True)
149
- if columns:
150
- x = df[columns].values
151
- x_scaled = scaler.inverse_transform(x)
152
- df_temp = pd.DataFrame(x_scaled, columns=columns, index = df.index)
153
- df[columns] = df_temp
154
-
155
- # set dummy features to NaN
156
- df.loc[df['dummy'],['class_id']+columns] = np.nan
163
+ print('Please provide a valid search range and memory value...')
164
+ return None
165
+ data['particle'] = data['particle'] + 1 # force track id to start at 1
166
+ df = data.rename(columns={'frame': column_labels['time'], 'x': column_labels['x'], 'y': column_labels['y'], 'particle': column_labels['track']})
167
+ df['state'] = 5.0; df['generation'] = 0.0; df['root'] = 1.0; df['parent'] = 1.0; df['dummy'] = False; df['z'] = 0.0;
168
+ data = df[[column_labels['track'],column_labels['time'],"z",column_labels['y'],column_labels['x']]].to_numpy()
169
+ print(f"{df=}")
170
+
171
+ if btrack_option:
172
+ df = df.merge(pd.DataFrame(properties),left_index=True, right_index=True)
173
+ if columns:
174
+ x = df[columns].values
175
+ x_scaled = scaler.inverse_transform(x)
176
+ df_temp = pd.DataFrame(x_scaled, columns=columns, index = df.index)
177
+ df[columns] = df_temp
178
+
179
+ # set dummy features to NaN
180
+ df.loc[df['dummy'],['class_id']+columns] = np.nan
181
+
157
182
  df = df.sort_values(by=[column_labels['track'],column_labels['time']])
158
183
  df = velocity_per_track(df, window_size=3, mode='bi')
159
184
 
160
185
  if channel_names is not None:
161
186
  df = rename_intensity_column(df, channel_names)
162
187
 
163
- df = write_first_detection_class(df, column_labels=column_labels)
188
+ df = write_first_detection_class(df, img_shape=volume, column_labels=column_labels)
164
189
 
165
190
  if clean_trajectories_kwargs is not None:
166
191
  df = clean_trajectories(df.copy(),**clean_trajectories_kwargs)
167
192
 
168
193
  df['ID'] = np.arange(len(df)).astype(int)
169
194
 
170
- if view_on_napari:
171
- view_on_napari_btrack(data,properties,graph,stack=stack,labels=labels,relabel=True)
195
+ invalid_cols = [c for c in list(df.columns) if c.startswith('Unnamed')]
196
+ if len(invalid_cols)>0:
197
+ df = df.drop(invalid_cols, axis=1)
198
+
199
+ # if view_on_napari:
200
+ # view_on_napari_btrack(data,properties,graph,stack=stack,labels=labels,relabel=True)
172
201
 
173
202
  if return_napari_data:
174
203
  napari_data = {"data": data, "properties": properties, "graph": graph}
@@ -921,44 +950,58 @@ def track_at_position(pos, mode, return_tracks=False, view_on_napari=False, thre
921
950
  # # else:
922
951
  # return None
923
952
 
924
- def write_first_detection_class(tab, column_labels={'track': "TRACK_ID", 'time': 'FRAME', 'x': 'POSITION_X', 'y': 'POSITION_Y'}):
953
+ def write_first_detection_class(df, img_shape=None, edge_threshold=20, column_labels={'track': "TRACK_ID", 'time': 'FRAME', 'x': 'POSITION_X', 'y': 'POSITION_Y'}):
925
954
 
926
955
  """
927
- Annotates a dataframe with the time of the first detection and classifies tracks based on their detection status.
956
+ Assigns a classification and first detection time to tracks in the given DataFrame. This function must be called
957
+ before any track post-processing.
928
958
 
929
- This function processes a dataframe containing tracking data, identifying the first point of detection for each
930
- track based on the x-coordinate values. It annotates the dataframe with the time of the first detection and
931
- assigns a class to each track indicating whether the first detection occurs at the start, during, or if there's
932
- no detection within the tracking data.
959
+ This function computes the first detection time and a detection class (`class_firstdetection`) for each track in the data.
960
+ Tracks that start on or near the image edge, or those detected at the initial frame, are marked with special classes.
933
961
 
934
962
  Parameters
935
963
  ----------
936
- tab : pandas.DataFrame
937
- The dataframe containing tracking data, expected to have columns for track ID, time, and spatial coordinates.
964
+ df : pandas.DataFrame
965
+ A DataFrame containing track data. Expected to have at least the columns specified in `column_labels` and `class_id` (mask value).
966
+
967
+ img_shape : tuple of int, optional
968
+ The shape of the image as `(height, width)`. Used to determine whether the first detection occurs near the image edge.
969
+
970
+ edge_threshold : int, optional, default=20
971
+ The distance in pixels from the image edge to consider a detection as near the edge.
972
+
938
973
  column_labels : dict, optional
939
- A dictionary mapping standard column names ('track', 'time', 'x', 'y') to the corresponding column names in
940
- `tab`. Default column names are 'TRACK_ID', 'FRAME', 'POSITION_X', 'POSITION_Y'.
974
+ A dictionary mapping logical column names to actual column names in `tab`. Keys include:
975
+ - `'track'`: The column indicating the track ID (default: `"TRACK_ID"`).
976
+ - `'time'`: The column indicating the frame/time (default: `"FRAME"`).
977
+ - `'x'`: The column indicating the X-coordinate (default: `"POSITION_X"`).
978
+ - `'y'`: The column indicating the Y-coordinate (default: `"POSITION_Y"`).
941
979
 
942
980
  Returns
943
981
  -------
944
982
  pandas.DataFrame
945
- The input dataframe `tab` with two additional columns: 'class_firstdetection' indicating the detection class,
946
- and 't_firstdetection' indicating the time of the first detection.
983
+ The input DataFrame `df` with two additional columns:
984
+ - `'class_firstdetection'`: A class assigned based on detection status:
985
+ - `0`: Valid detection not near the edge and not at the initial frame.
986
+ - `2`: Detection near the edge, at the initial frame, or no detection available.
987
+ - `'t_firstdetection'`: The adjusted first detection time (in frame units):
988
+ - `-1`: Indicates no valid detection or detection near the edge.
989
+ - A float value representing the adjusted first detection time otherwise.
947
990
 
948
991
  Notes
949
992
  -----
950
- - Detection is based on the presence of non-NaN values in the 'x' column for each track.
951
- - Tracks with their first detection at the first time point are classified differently (`cclass=2`) and assigned
952
- a `t_first` of -1, indicating no prior detection.
953
- - The function assumes uniform time steps between each frame in the tracking data.
954
-
993
+ - The function assumes that tracks are grouped and sorted by track ID and frame.
994
+ - Detections near the edge or at the initial frame (frame 0) are considered invalid and assigned special values.
995
+ - If `img_shape` is not provided, edge checks are skipped.
955
996
  """
956
997
 
957
- tab = tab.sort_values(by=[column_labels['track'],column_labels['time']])
958
- for tid,track_group in tab.groupby(column_labels['track']):
998
+ df = df.sort_values(by=[column_labels['track'],column_labels['time']])
999
+ for tid,track_group in df.groupby(column_labels['track']):
959
1000
  indices = track_group.index
960
- detection = track_group[column_labels['x']].values
1001
+ detection = track_group['class_id'].values
961
1002
  timeline = track_group[column_labels['time']].values
1003
+ positions_x = track_group[column_labels['x']].values
1004
+ positions_y = track_group[column_labels['y']].values
962
1005
  dt = 1
963
1006
 
964
1007
  # Initialize
@@ -966,8 +1009,14 @@ def write_first_detection_class(tab, column_labels={'track': "TRACK_ID", 'time':
966
1009
 
967
1010
  if np.any(detection==detection):
968
1011
  t_first = timeline[detection==detection][0]
1012
+ x_first = positions_x[detection==detection][0]; y_first = positions_y[detection==detection][0];
1013
+
1014
+ edge_test = False
1015
+ if img_shape is not None:
1016
+ edge_test = (x_first < edge_threshold) or (y_first < edge_threshold) or (y_first > (img_shape[0] - edge_threshold)) or (x_first > (img_shape[1] - edge_threshold))
1017
+
969
1018
  cclass = 0
970
- if t_first<=0:
1019
+ if t_first<=0 or edge_test:
971
1020
  t_first = -1
972
1021
  cclass = 2
973
1022
  else:
@@ -978,10 +1027,10 @@ def write_first_detection_class(tab, column_labels={'track': "TRACK_ID", 'time':
978
1027
  t_first = -1
979
1028
  cclass = 2
980
1029
 
981
- tab.loc[indices, 'class_firstdetection'] = cclass
982
- tab.loc[indices, 't_firstdetection'] = t_first
1030
+ df.loc[indices, 'class_firstdetection'] = cclass
1031
+ df.loc[indices, 't_firstdetection'] = t_first
983
1032
 
984
- return tab
1033
+ return df
985
1034
 
986
1035
 
987
1036
 
celldetective/utils.py CHANGED
@@ -30,6 +30,15 @@ from skimage.morphology import disk
30
30
  from scipy.stats import ks_2samp
31
31
  from cliffs_delta import cliffs_delta
32
32
 
33
+
34
+ def extract_cols_from_table_list(tables, nrows=1):
35
+ all_columns = []
36
+ for tab in tables:
37
+ cols = pd.read_csv(tab, nrows=1).columns.tolist()
38
+ all_columns.extend(cols)
39
+ all_columns = np.unique(all_columns)
40
+ return all_columns
41
+
33
42
  def safe_log(array):
34
43
 
35
44
  if isinstance(array,int) or isinstance(array,float):
@@ -415,7 +424,7 @@ def estimate_unreliable_edge(activation_protocol=[['gauss',2],['std',4]]):
415
424
  else:
416
425
  edge=0
417
426
  for fct in activation_protocol:
418
- if isinstance(fct[1],(int,np.int_)):
427
+ if isinstance(fct[1],(int,np.int_)) and not fct[0]=='invert':
419
428
  edge+=fct[1]
420
429
  return edge
421
430
 
@@ -547,8 +556,14 @@ def extract_cols_from_query(query: str):
547
556
  # Add the name to the globals dictionary with a dummy value.
548
557
  variables[name] = None
549
558
 
550
- return list(variables.keys())
559
+ # Reverse mangling for special characters in column names.
560
+ def demangle_column_name(name):
561
+ if name.startswith("BACKTICK_QUOTED_STRING_"):
562
+ # Unquote backtick-quoted string.
563
+ return name[len("BACKTICK_QUOTED_STRING_"):].replace("_DOT_", ".").replace("_SLASH_", "/")
564
+ return name
551
565
 
566
+ return [demangle_column_name(name) for name in variables.keys()]
552
567
 
553
568
  def create_patch_mask(h, w, center=None, radius=None):
554
569
 
@@ -646,15 +661,14 @@ def rename_intensity_column(df, channels):
646
661
  channel_names = np.array(channels)
647
662
  channel_indices = np.arange(len(channel_names),dtype=int)
648
663
 
649
- if np.any(['intensity' in c for c in df.columns]):
664
+ if np.any(['intensity' in c for c in list(df.columns)]):
650
665
 
651
666
  intensity_indices = [s.startswith('intensity') for s in df.columns]
652
667
  intensity_columns = df.columns[intensity_indices]
653
668
 
654
- if len(channel_names) > 1:
669
+ if len(channel_names) >= 1:
655
670
  to_rename = {}
656
671
  for k in range(len(intensity_columns)):
657
- #print(intensity_columns[k])
658
672
 
659
673
  sections = np.array(re.split('-|_', intensity_columns[k]))
660
674
  test_digit = np.array([s.isdigit() for s in sections])
@@ -664,7 +678,11 @@ def rename_intensity_column(df, channels):
664
678
  new_name = np.delete(sections, np.where(test_digit)[0]) #np.where(test_digit)[0]
665
679
  new_name = '_'.join(list(new_name))
666
680
  new_name = new_name.replace('intensity', channel_name)
667
- to_rename.update({intensity_columns[k]: new_name.replace('-','_')})
681
+ new_name = new_name.replace('-','_')
682
+ new_name = new_name.replace('_nanmean','_mean')
683
+
684
+ to_rename.update({intensity_columns[k]: new_name})
685
+
668
686
  if 'centre' in intensity_columns[k]:
669
687
  # sections = np.array(re.split('-|_', intensity_columns[k]))
670
688
  measure = np.array(re.split('-|_', new_name))
@@ -1232,7 +1250,10 @@ def ConfigSectionMap(path,section):
1232
1250
  Config = configparser.ConfigParser()
1233
1251
  Config.read(path)
1234
1252
  dict1 = {}
1235
- options = Config.options(section)
1253
+ try:
1254
+ options = Config.options(section)
1255
+ except:
1256
+ return None
1236
1257
  for option in options:
1237
1258
  try:
1238
1259
  dict1[option] = Config.get(section, option)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: celldetective
3
- Version: 1.3.4.post1
3
+ Version: 1.3.6.post1
4
4
  Summary: description
5
5
  Home-page: http://github.com/remyeltorro/celldetective
6
6
  Author: Rémy Torro
@@ -20,7 +20,7 @@ Requires-Dist: cellpose<3
20
20
  Requires-Dist: scikit-learn
21
21
  Requires-Dist: btrack
22
22
  Requires-Dist: tensorflow~=2.15.0
23
- Requires-Dist: napari
23
+ Requires-Dist: napari<0.6.0
24
24
  Requires-Dist: tqdm
25
25
  Requires-Dist: mahotas
26
26
  Requires-Dist: fonticon-materialdesignicons6
@@ -42,6 +42,7 @@ Requires-Dist: pytest-qt
42
42
  Requires-Dist: h5py
43
43
  Requires-Dist: cliffs_delta
44
44
  Requires-Dist: requests
45
+ Requires-Dist: trackpy
45
46
 
46
47
  # Celldetective
47
48
 
@@ -1,48 +1,48 @@
1
1
  celldetective/__init__.py,sha256=bi3SGTMo6s2qQBsJAaKy-a4xaGcTQVW8zsqaiX5XKeY,139
2
2
  celldetective/__main__.py,sha256=bxTlSvbKhqn3LW_azd2baDCnDsgb37PAP9DfuAJ1_5M,1844
3
- celldetective/_version.py,sha256=O9z4W-emw0sUnueuXoMBlkVWoLZBTUjF8-PzKP_tSiI,28
4
- celldetective/events.py,sha256=R6GDtiH0ZuEbad0R-nrlTHmho0Hly3QyyVYx2dD__P0,8051
3
+ celldetective/_version.py,sha256=bW6H44PSm7DIqPxnn6PKr6QzSOJZU8d_cyKDCh6Mv18,28
4
+ celldetective/events.py,sha256=GtlFgfSQD8F7FBFCptWU0R8R3BL_UoMBzmGJ7IyAgeE,8143
5
5
  celldetective/extra_properties.py,sha256=y556D6EMjLGhtjDqRoOTRGa85XxTIe0K1Asb26VZXmo,5643
6
- celldetective/filters.py,sha256=9w4JyPH2cISRu7gtUDVsm9whiMMWxuc1vwhfaq3zWkY,3683
7
- celldetective/io.py,sha256=_SO32G5Sc60vHQhQj7gXvDNTXjVd1uZ8x1HnFxCYU0g,90833
8
- celldetective/measure.py,sha256=PXi13O6wjXbgj53o-C8DEWLVkmy9qb4vocmq1irPVV0,57450
6
+ celldetective/filters.py,sha256=-UuS_aH_JxEPMWlb7VAaIsNQUXlARhfZ1DL_qypGFA0,3892
7
+ celldetective/io.py,sha256=cNr7pg8MWGL9V28pfDjZsiriYnU19oFLnhC5P6JqT9k,122535
8
+ celldetective/measure.py,sha256=b0pZckV9dMJEUoLqvUfLmUWo7z0xPc0Xe4qnvaoq_KY,60066
9
9
  celldetective/neighborhood.py,sha256=s-zVsfGnPlqs6HlDJCXRh21lLiPKbA_S1JC6uZvfG_0,56712
10
- celldetective/preprocessing.py,sha256=WmetQCgmHK6fo8AuwESPLab05WgeIy8ElBs-9KM-Cco,44081
11
- celldetective/relative_measurements.py,sha256=av5DiGlGsbILPav8aVcFlhbmbPLPZPxCB5qQejzhiRY,30400
10
+ celldetective/preprocessing.py,sha256=Wlt_PJua97CpMuWe_M65znUmz_yjYPqWIcs2ZK_RLgk,44109
11
+ celldetective/relative_measurements.py,sha256=ZviXp6-z_SB60e7z3GznqfEngv70waOK0sMxm_q-JJA,30546
12
12
  celldetective/segmentation.py,sha256=NjAVaVpZufpJ-LIvBx5UFH6j5kjRKE6EVLjttDrqaqs,30826
13
- celldetective/signals.py,sha256=ueRZmmMuVSNFpFAHhF06xE8zr4qjuN8i-jxJj_qyfVI,121475
14
- celldetective/tracking.py,sha256=e6XMunjVRhBnv1cRF66hkK-Hbti5KyPrs2mnR6qKpvU,38027
15
- celldetective/utils.py,sha256=oP_GHPdJJHK9s8sIlzKEXfTjCvzxAifdYYynkSMfu7A,89145
13
+ celldetective/signals.py,sha256=mrQjHA7xDgL6EUVk9U359sUwSgSvSCsdNJDt0truCA4,121574
14
+ celldetective/tracking.py,sha256=babNFkxtYDwoAl_WJcZC-GYItafKShV2PLSWimxM6oA,40361
15
+ celldetective/utils.py,sha256=5nxfYnl0xsfocPg6BH2SmZ4n1jKMUUWXVZW3-xabXbk,89802
16
16
  celldetective/datasets/segmentation_annotations/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  celldetective/datasets/signal_annotations/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  celldetective/gui/InitWindow.py,sha256=sQSwfZ6SIQeZDQ_3KZoMO2MH9Fs9rhWeqxzEf9PFjEM,14534
19
19
  celldetective/gui/__init__.py,sha256=2_r2xfOj4_2xj0yBkCTIfzlF94AHKm-j6Pvpd7DddQc,989
20
20
  celldetective/gui/about.py,sha256=FJZrj6C-p6uqp_3UaprKosuW-Sw9_HPNQAvFbis9Gdk,1749
21
21
  celldetective/gui/analyze_block.py,sha256=h0sp7Tk3hZFM8w0yTidwIjZX4WRI-lQF3JCFObrLCPo,2761
22
- celldetective/gui/btrack_options.py,sha256=OrvbG5coZhLRk5jtXiLFJu34z1hWHN9kHkBiZ7XMZoI,39269
23
- celldetective/gui/classifier_widget.py,sha256=mo7Gel3DKhFTUt184WvF0AOsw4HQ7kC8qrkSf8jr3hY,18412
24
- celldetective/gui/configure_new_exp.py,sha256=Eyr-M4FH-4xrUJbIGNdKXAtXb_ULr8lCol26JSzXEww,20125
25
- celldetective/gui/control_panel.py,sha256=Xr8W37KkRoR2R4ILsZbclnU6-g3WP1WjjTz6k39PN_8,21645
26
- celldetective/gui/generic_signal_plot.py,sha256=cfPvNcLtsVp3xvKyOg1ekMKXcomN6fEnlowUnXrYK2c,36293
27
- celldetective/gui/gui_utils.py,sha256=b6L4mThjN8upgXx4YeNRrfSSCF2l1epb_uEU8cc31F8,34171
22
+ celldetective/gui/btrack_options.py,sha256=tY0XiDcsI4KDgwZtcaP7HWLJ_isxamM-7sFX-m5Dcwk,44662
23
+ celldetective/gui/classifier_widget.py,sha256=UyElqL9Rq5cKcM6i8ZLGCqkMqqnSDaw6i_hRoV_7WSE,19817
24
+ celldetective/gui/configure_new_exp.py,sha256=sRBGhMoQUP8-XchmfV6VvuFHceS4Q8qPY2ua7DQOaHI,20754
25
+ celldetective/gui/control_panel.py,sha256=CKbn6K7_s_K6r-hJMAJmWhDjj8mrYhk_ycr8x_8DIDQ,21710
26
+ celldetective/gui/generic_signal_plot.py,sha256=iINeKvItGL4X8ONDRM7yv1zovEX1hhLreeOXbxiKTy0,36078
27
+ celldetective/gui/gui_utils.py,sha256=1-B5f1sij-3jM-Y9IuhoLH7Skcua3r6V0w8yNdX-Nr0,39358
28
28
  celldetective/gui/json_readers.py,sha256=Su3angSobroeGrrumGgQcs3Cr_9l9p52-Hfm3qneVcI,3664
29
29
  celldetective/gui/layouts.py,sha256=XsqiHR58DXsG5SSD5S8KOtUv4yw-y-s2_wZx_XsHeJs,52013
30
- celldetective/gui/measurement_options.py,sha256=MnJ9dToJb-_UppqHEyFoIvqY8M2cneTGmqxMToeTJ48,39579
31
- celldetective/gui/neighborhood_options.py,sha256=BvWwsIX1KWogUgHWRZptqY3ZRmH1aj7r8tiLmbRFhW4,19783
30
+ celldetective/gui/measurement_options.py,sha256=cfiC4lq-XqY4Sa4Vkw5mys7JKaa9tE2BgeN8_k-SIDY,40355
31
+ celldetective/gui/neighborhood_options.py,sha256=IUzcE8RrnNbDuLebvIyUxN0-mL05SexlWPzqAWZDPuQ,19814
32
32
  celldetective/gui/plot_measurements.py,sha256=n0pDUcYcsKlSMaUaBSVplGziuWp_7jKaeXdREs-MqyI,50848
33
- celldetective/gui/plot_signals_ui.py,sha256=dLClQYdQcs98Dq6RWixWXM7_iS67CicOe695bA9LM-w,16447
34
- celldetective/gui/process_block.py,sha256=tk3zhhXhutszmFP3T7zbXnoCOZRbFUHPBR4cNNaHQOk,68683
33
+ celldetective/gui/plot_signals_ui.py,sha256=ASHXrFr5ctCs5ppWmC7KqU1EtzqbvI8D1FKtvd2dAiQ,16495
34
+ celldetective/gui/process_block.py,sha256=OCEYCRd8s3rT9x4Rs9ut3s7cM4bv9spKjhvASRPyOgY,68746
35
35
  celldetective/gui/retrain_segmentation_model_options.py,sha256=ACeQ_DdSLy1EK0z_S_9v-0HOiLXjUmrz4sdvHWZT6FI,23330
36
36
  celldetective/gui/retrain_signal_model_options.py,sha256=XigNdGlNu3KWB_MYBcKQhfXjcWwVZNMmu0qmxNoo14E,21919
37
37
  celldetective/gui/seg_model_loader.py,sha256=vWvPMU6nkTiQfI-x2WjQHrdJGFdV4a4Ne-4YIOq_YZ8,18153
38
- celldetective/gui/signal_annotator.py,sha256=gZtuWoVWjaIzxy5SL1Cg2rBrsH9-s-oYSxJe7CQeEiY,88656
39
- celldetective/gui/signal_annotator2.py,sha256=fAgkNexxvcnY4KvIxtgHKF3B9K-wsgfA8KbkALq4UPY,108945
38
+ celldetective/gui/signal_annotator.py,sha256=xJh69pzOFGbM3V2ySXL2BSav6Tp2mhF0LyPBpFWgp7w,88892
39
+ celldetective/gui/signal_annotator2.py,sha256=0h7WUFnOEHXoyLobDDRcDcTIC-DIF9q2ykx6aI-5g1c,106339
40
40
  celldetective/gui/signal_annotator_options.py,sha256=ztFFgA70SJ0QkntxYGsgDNCvSuSR5GjF7_J6pYVYc1g,11020
41
41
  celldetective/gui/styles.py,sha256=awg5NfGWUoM4V_LpVlmPP7JorpofiLVNqLBv4zRy89E,5058
42
- celldetective/gui/survival_ui.py,sha256=7qUenqEIaWEwdf-nKE1gN0LAdybgQbRLb3OJMTI9bfk,10193
43
- celldetective/gui/tableUI.py,sha256=2tBZN3X1nrBD_t58yaCY4NENWeHtgvaN0IcKzZn18SM,50500
44
- celldetective/gui/thresholds_gui.py,sha256=6Lgr_CK2LBn_gMsWf0gIQvQIQSMg3oIhFfknFeg8Fh4,50721
45
- celldetective/gui/viewers.py,sha256=0KmtAKZUNY5xpKFcFajgc1Jbnf_86rw_ooX6UrMmEHc,46328
42
+ celldetective/gui/survival_ui.py,sha256=J4ZYjX8ne0wT0ruQu9WL3WfLnRIAQalkaAR8ngb7PkI,14170
43
+ celldetective/gui/tableUI.py,sha256=0bWEECh6BCRV5K2jFaZe9c3H78vBUxYFppplKQiLteU,51022
44
+ celldetective/gui/thresholds_gui.py,sha256=VjCVBCDsNh_LoXfEqUn32nsYQwO9-Elh3Gl1RBv7acc,48756
45
+ celldetective/gui/viewers.py,sha256=mne5GLFAjv-vxMABXP7I9VhrJGtPnZj560HLdlwDZSU,47806
46
46
  celldetective/gui/help/DL-segmentation-strategy.json,sha256=59jVtn8pECbCqPQwJifgViVYTF1AxLQDIkNJMS7CJuk,1143
47
47
  celldetective/gui/help/Threshold-vs-DL.json,sha256=SELQk3qF8xcwmkX686Bqrr7i5KiXqN7r4jbUydCLRDU,603
48
48
  celldetective/gui/help/cell-populations.json,sha256=wP0ekhokb9oHE3XqOQrC5ARewNgOlv0GJrQeVQyMJzg,1075
@@ -80,11 +80,11 @@ celldetective/models/tracking_configs/no_z_motion.json,sha256=b4RWOJ0w6Y2e0vJYwK
80
80
  celldetective/models/tracking_configs/ricm.json,sha256=L-vmwCR1f89U-qnH2Ms0cBfPFR_dxIWoe2ccH8V-QBA,2727
81
81
  celldetective/models/tracking_configs/ricm2.json,sha256=DDjJ6ScYcDWvlsy7ujPID8v8H28vcNcMuZmNR8XmGxo,2718
82
82
  celldetective/scripts/analyze_signals.py,sha256=YE05wZujl2hQFWkvqATBcCx-cAd_V3RxnvKoh0SB7To,2194
83
- celldetective/scripts/measure_cells.py,sha256=jUwPSjIzR4sCvjer_K5vSlRQX3e8AhJE3xhUbevES7c,12143
83
+ celldetective/scripts/measure_cells.py,sha256=szZ79zWPWbr-13zU3RPIYnsUwW4xAx-YwKKbvhulTK4,12606
84
84
  celldetective/scripts/measure_relative.py,sha256=L_NjIUfHSGupkAKLZkubBHJdZh0ugPhCTJem80b0zMM,4261
85
- celldetective/scripts/segment_cells.py,sha256=bnNacgp_6qpb1fvwPizxVctsUNiFBegKalo-PSpXPEU,8262
85
+ celldetective/scripts/segment_cells.py,sha256=CxAuqmSslDoq1zFlZrgt4-ZORVCv-bF-kdXHWQgf8MY,8216
86
86
  celldetective/scripts/segment_cells_thresholds.py,sha256=6ERg-hxdHMSgXPQSBPtYt2lccTlkz9ZLktYgb57Avmw,5168
87
- celldetective/scripts/track_cells.py,sha256=ezNpenAYBz010iMZNRIk0qwGAceiXRLvY7ZxoQcT2IM,8052
87
+ celldetective/scripts/track_cells.py,sha256=r_EaOIPgwGewHsvcbLaqTkxp4PQ4uDLq-E0bbUDZ1p4,8581
88
88
  celldetective/scripts/train_segmentation_model.py,sha256=XExaGg8kkdirgN206J0mwiWtqeRE076-Ld2b89tReAI,9229
89
89
  celldetective/scripts/train_signal_model.py,sha256=D643wKVYg-LWHF2VU9FWKSuazXrpCpQK0YjGqoIimD0,3167
90
90
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -99,9 +99,9 @@ tests/test_segmentation.py,sha256=k1b_zIZdlytEdJcHjAUQEO3gTBAHtv5WvrwQN2xD4kc,34
99
99
  tests/test_signals.py,sha256=No4cah6KxplhDcKXnU8RrA7eDla4hWw6ccf7xGnBokU,3599
100
100
  tests/test_tracking.py,sha256=8hebWSqEIuttD1ABn-6dKCT7EXKRR7-4RwyFWi1WPFo,8800
101
101
  tests/test_utils.py,sha256=NKRCAC1d89aBK5cWjTb7-pInYow901RrT-uBlIdz4KI,3692
102
- celldetective-1.3.4.post1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
103
- celldetective-1.3.4.post1.dist-info/METADATA,sha256=-fcPPLCWNqV8h4WdVm1bceP9_ujji_v52WeylF4tdZ8,10534
104
- celldetective-1.3.4.post1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
105
- celldetective-1.3.4.post1.dist-info/entry_points.txt,sha256=2NU6_EOByvPxqBbCvjwxlVlvnQreqZ3BKRCVIKEv3dg,62
106
- celldetective-1.3.4.post1.dist-info/top_level.txt,sha256=6rsIKKfGMKgud7HPuATcpq6EhdXwcg_yknBVWn9x4C4,20
107
- celldetective-1.3.4.post1.dist-info/RECORD,,
102
+ celldetective-1.3.6.post1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
103
+ celldetective-1.3.6.post1.dist-info/METADATA,sha256=wbiMcVjmdJpkTzkpfmGiWwS5sgeRZ4H5dEHPIWUBCqM,10563
104
+ celldetective-1.3.6.post1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
105
+ celldetective-1.3.6.post1.dist-info/entry_points.txt,sha256=2NU6_EOByvPxqBbCvjwxlVlvnQreqZ3BKRCVIKEv3dg,62
106
+ celldetective-1.3.6.post1.dist-info/top_level.txt,sha256=6rsIKKfGMKgud7HPuATcpq6EhdXwcg_yknBVWn9x4C4,20
107
+ celldetective-1.3.6.post1.dist-info/RECORD,,