celldetective 1.2.2.post2__py3-none-any.whl → 1.3.0.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.
celldetective/measure.py CHANGED
@@ -980,7 +980,6 @@ def blob_detection(image, label, threshold, diameter):
980
980
 
981
981
  ### Classification ####
982
982
 
983
-
984
983
  def estimate_time(df, class_attr, model='step_function', class_of_interest=[2], r2_threshold=0.5):
985
984
 
986
985
  """
@@ -1027,6 +1026,7 @@ def estimate_time(df, class_attr, model='step_function', class_of_interest=[2],
1027
1026
  df = df.sort_values(by=sort_cols,ignore_index=True)
1028
1027
  df = df.reset_index(drop=True)
1029
1028
 
1029
+
1030
1030
  for tid,group in df.loc[df[class_attr].isin(class_of_interest)].groupby(sort_cols):
1031
1031
 
1032
1032
  indices = group.index
@@ -1034,21 +1034,19 @@ def estimate_time(df, class_attr, model='step_function', class_of_interest=[2],
1034
1034
 
1035
1035
  group_clean = group.dropna(subset=status_col)
1036
1036
  status_signal = group_clean[status_col].values
1037
+ if np.all(np.array(status_signal)==1):
1038
+ continue
1039
+
1037
1040
  timeline = group_clean['FRAME'].values
1038
-
1039
1041
  frames = group_clean['FRAME'].to_numpy()
1040
1042
  status_values = group_clean[status_col].to_numpy()
1041
1043
  t_first = group['t_firstdetection'].to_numpy()[0]
1042
1044
 
1043
1045
  try:
1044
-
1045
- popt, pcov = curve_fit(eval(model), timeline.astype(int), status_signal, p0=[df['FRAME'].max()//2, 0.8],maxfev=30000)
1046
+ popt, pcov = curve_fit(eval(model), timeline.astype(int), status_signal, p0=[max(timeline)//2, 0.8],maxfev=100000)
1046
1047
  values = [eval(model)(t, *popt) for t in timeline]
1047
1048
  r2 = r2_score(status_signal,values)
1048
-
1049
- except Exception as e:
1050
-
1051
- print(e)
1049
+ except Exception:
1052
1050
  df.loc[indices, class_attr] = 2.0
1053
1051
  df.loc[indices, class_attr.replace('class','t')] = -1
1054
1052
  continue
@@ -1064,7 +1062,7 @@ def estimate_time(df, class_attr, model='step_function', class_of_interest=[2],
1064
1062
  return df
1065
1063
 
1066
1064
 
1067
- def interpret_track_classification(df, class_attr, irreversible_event=False, unique_state=False,r2_threshold=0.5):
1065
+ def interpret_track_classification(df, class_attr, irreversible_event=False, unique_state=False,r2_threshold=0.5, percentile_recovery=50):
1068
1066
 
1069
1067
  """
1070
1068
  Interpret and classify tracked cells based on their status signals.
@@ -1123,15 +1121,15 @@ def interpret_track_classification(df, class_attr, irreversible_event=False, uni
1123
1121
 
1124
1122
  if irreversible_event:
1125
1123
 
1126
- df = classify_irreversible_events(df, class_attr, r2_threshold=0.5)
1127
-
1124
+ df = classify_irreversible_events(df, class_attr, r2_threshold=r2_threshold, percentile_recovery=percentile_recovery)
1125
+
1128
1126
  elif unique_state:
1129
1127
 
1130
1128
  df = classify_unique_states(df, class_attr, percentile=50)
1131
1129
 
1132
1130
  return df
1133
1131
 
1134
- def classify_irreversible_events(df, class_attr, r2_threshold=0.5, percentile_recovery=95):
1132
+ def classify_irreversible_events(df, class_attr, r2_threshold=0.5, percentile_recovery=50):
1135
1133
 
1136
1134
  """
1137
1135
  Classify irreversible events in a tracked dataset based on the status of cells and transitions.
@@ -1179,6 +1177,12 @@ def classify_irreversible_events(df, class_attr, r2_threshold=0.5, percentile_re
1179
1177
  stat_col = class_attr.replace('class','status')
1180
1178
 
1181
1179
  for tid,track in df.groupby(sort_cols):
1180
+
1181
+ # Set status to 0.0 before first detection
1182
+ t_firstdetection = track['t_firstdetection'].values[0]
1183
+ indices_pre_detection = track.loc[track['FRAME']<=t_firstdetection,class_attr].index
1184
+ track.loc[indices_pre_detection,stat_col] = 0.0
1185
+ df.loc[indices_pre_detection,stat_col] = 0.0
1182
1186
 
1183
1187
  track_valid = track.dropna(subset=stat_col)
1184
1188
  indices_valid = track_valid[class_attr].index
@@ -1193,16 +1197,20 @@ def classify_irreversible_events(df, class_attr, r2_threshold=0.5, percentile_re
1193
1197
  elif np.all([s==1 for s in status_values]):
1194
1198
  # all positive, event already observed
1195
1199
  df.loc[indices, class_attr] = 2
1196
- df.loc[indices, class_attr.replace('class','status')] = 2
1200
+ #df.loc[indices, class_attr.replace('class','status')] = 2
1197
1201
  else:
1198
1202
  # ambiguity, possible transition
1199
1203
  df.loc[indices, class_attr] = 2
1200
1204
 
1205
+ print("Classes after initial pass: ",df.loc[df['FRAME']==0,class_attr].value_counts())
1206
+
1201
1207
  df.loc[df[class_attr]!=2, class_attr.replace('class', 't')] = -1
1202
1208
  df = estimate_time(df, class_attr, model='step_function', class_of_interest=[2],r2_threshold=r2_threshold)
1203
-
1209
+ print("Classes after fit: ", df.loc[df['FRAME']==0,class_attr].value_counts())
1210
+
1204
1211
  # Revisit class 2 cells to classify as neg/pos with percentile tolerance
1205
1212
  df.loc[df[class_attr]==2,:] = classify_unique_states(df.loc[df[class_attr]==2,:].copy(), class_attr, percentile_recovery)
1213
+ print("Classes after unique state recovery: ",df.loc[df['FRAME']==0,class_attr].value_counts())
1206
1214
 
1207
1215
  return df
1208
1216
 
@@ -1251,14 +1259,17 @@ def classify_unique_states(df, class_attr, percentile=50):
1251
1259
 
1252
1260
  stat_col = class_attr.replace('class','status')
1253
1261
 
1262
+
1254
1263
  for tid,track in df.groupby(sort_cols):
1255
1264
 
1265
+
1256
1266
  track_valid = track.dropna(subset=stat_col)
1257
1267
  indices_valid = track_valid[class_attr].index
1258
1268
 
1259
1269
  indices = track[class_attr].index
1260
1270
  status_values = track_valid[stat_col].to_numpy()
1261
1271
 
1272
+
1262
1273
  frames = track_valid['FRAME'].to_numpy()
1263
1274
  t_first = track['t_firstdetection'].to_numpy()[0]
1264
1275
  perc_status = np.nanpercentile(status_values[frames>=t_first], percentile)
@@ -1324,10 +1335,14 @@ def classify_cells_from_query(df, status_attr, query):
1324
1335
 
1325
1336
 
1326
1337
  # Initialize all states to 0
1327
- df[status_attr] = 0
1338
+ if not status_attr.startswith('status_'):
1339
+ status_attr = 'status_'+status_attr
1340
+
1341
+ df = df.copy()
1342
+ df.loc[:,status_attr] = 0
1343
+
1328
1344
  cols = extract_cols_from_query(query)
1329
1345
  cols_in_df = np.all([c in list(df.columns) for c in cols], axis=0)
1330
-
1331
1346
  if query=='':
1332
1347
  print('The provided query is empty...')
1333
1348
  else:
@@ -1340,8 +1355,21 @@ def classify_cells_from_query(df, status_attr, query):
1340
1355
  df.loc[selection, status_attr] = 1
1341
1356
  else:
1342
1357
  df.loc[:, status_attr] = np.nan
1343
-
1344
1358
  except Exception as e:
1345
- print("The query could not be understood. No filtering was applied. {e}...")
1359
+ print(f"The query could not be understood. No filtering was applied. {e}...")
1346
1360
  return None
1361
+ return df.copy()
1362
+
1363
+ def classify_tracks_from_query(df, event_name, query, irreversible_event=True, unique_state=False, r2_threshold=0.5, percentile_recovery=50):
1364
+
1365
+ status_attr = "status_"+event_name
1366
+ df = classify_cells_from_query(df, status_attr, query)
1367
+ class_attr = "class_"+event_name
1368
+
1369
+ name_map = {status_attr: class_attr}
1370
+ df = df.drop(list(set(name_map.values()) & set(df.columns)), axis=1).rename(columns=name_map)
1371
+ df.reset_index(inplace=True, drop=True)
1372
+
1373
+ df = interpret_track_classification(df, class_attr, irreversible_event=irreversible_event, unique_state=unique_state, r2_threshold=r2_threshold, percentile_recovery=percentile_recovery)
1374
+
1347
1375
  return df
@@ -28,7 +28,7 @@ import subprocess
28
28
  abs_path = os.sep.join([os.path.split(os.path.dirname(os.path.realpath(__file__)))[0],'celldetective'])
29
29
 
30
30
  def segment(stack, model_name, channels=None, spatial_calibration=None, view_on_napari=False,
31
- use_gpu=True, channel_axis=-1):
31
+ use_gpu=True, channel_axis=-1, cellprob_threshold=None, flow_threshold=None):
32
32
 
33
33
  """
34
34
 
@@ -50,10 +50,6 @@ def segment(stack, model_name, channels=None, spatial_calibration=None, view_on_
50
50
  Whether to visualize the segmentation results using Napari. Default is False.
51
51
  use_gpu : bool, optional
52
52
  Whether to use GPU acceleration if available. Default is True.
53
- time_flat_normalization : bool, optional
54
- Whether to perform time-flat normalization on the stack before segmentation. Default is False.
55
- time_flat_percentiles : tuple, optional
56
- The percentiles used for time-flat normalization. Default is (0.0, 99.99).
57
53
 
58
54
  Returns
59
55
  -------
@@ -95,6 +91,9 @@ def segment(stack, model_name, channels=None, spatial_calibration=None, view_on_
95
91
  assert len(channels)==stack.shape[-1],f'The channel names provided do not match with the expected number of channels in the stack: {stack.shape[-1]}.'
96
92
 
97
93
  required_channels = input_config['channels']
94
+ channel_intersection = [ch for ch in channels if ch in required_channels]
95
+ assert len(channel_intersection)>0,'None of the channels required by the model can be found in the images to segment... Abort.'
96
+
98
97
  channel_indices = _extract_channel_indices(channels, required_channels)
99
98
 
100
99
  required_spatial_calibration = input_config['spatial_calibration']
@@ -108,10 +107,13 @@ def segment(stack, model_name, channels=None, spatial_calibration=None, view_on_
108
107
  diameter = input_config['diameter']
109
108
  # if diameter!=30:
110
109
  # required_spatial_calibration = None
111
- cellprob_threshold = input_config['cellprob_threshold']
112
- flow_threshold = input_config['flow_threshold']
110
+ if cellprob_threshold is None:
111
+ cellprob_threshold = input_config['cellprob_threshold']
112
+ if flow_threshold is None:
113
+ flow_threshold = input_config['flow_threshold']
113
114
 
114
115
  scale = _estimate_scale_factor(spatial_calibration, required_spatial_calibration)
116
+ print(f"{spatial_calibration=} {required_spatial_calibration=} Scale = {scale}...")
115
117
 
116
118
  if model_type=='stardist':
117
119
 
@@ -145,13 +147,19 @@ def segment(stack, model_name, channels=None, spatial_calibration=None, view_on_
145
147
  channel_indices = np.array(channel_indices)
146
148
  none_channel_indices = np.where(channel_indices==None)[0]
147
149
  channel_indices[channel_indices==None] = 0
148
- print(channel_indices)
149
150
 
150
- frame = stack[t,:,:,channel_indices.astype(int)].astype(float)
151
+ frame = stack[t]
152
+ #frame = stack[t,:,:,channel_indices.astype(int)].astype(float)
151
153
  if frame.ndim==2:
152
154
  frame = frame[:,:,np.newaxis]
153
155
  if frame.ndim==3 and np.array(frame.shape).argmin()==0:
154
156
  frame = np.moveaxis(frame,0,-1)
157
+
158
+ frame_to_segment = np.zeros((frame.shape[0], frame.shape[1], len(required_channels))).astype(float)
159
+ for ch in channel_intersection:
160
+ idx = required_channels.index(ch)
161
+ frame_to_segment[:,:,idx] = frame[:,:,channels.index(ch)]
162
+ frame = frame_to_segment
155
163
  template = frame.copy()
156
164
 
157
165
  values = []
celldetective/utils.py CHANGED
@@ -26,6 +26,8 @@ import re
26
26
  from scipy.ndimage.morphology import distance_transform_edt
27
27
  from scipy import ndimage
28
28
  from skimage.morphology import disk
29
+ from scipy.stats import ks_2samp
30
+ from cliffs_delta import cliffs_delta
29
31
 
30
32
  def contour_of_instance_segmentation(label, distance):
31
33
 
@@ -1183,27 +1185,10 @@ def _extract_channel_indices(channels, required_channels):
1183
1185
  ch_idx = channels.index(c)
1184
1186
  channel_indices.append(ch_idx)
1185
1187
  except Exception as e:
1186
- print(f"Error {e}. The channel required by the model is not available in your data... Check the configuration file.")
1187
- channels = None
1188
- break
1188
+ channel_indices.append(None)
1189
1189
  else:
1190
1190
  channel_indices.append(None)
1191
1191
 
1192
- # if channels is not None:
1193
- # channel_indices = []
1194
- # for ch in required_channels:
1195
-
1196
- # try:
1197
- # idx = channels.index(ch)
1198
- # except ValueError:
1199
- # print('Mismatch between the channels required by the model and the provided channels.')
1200
- # return None
1201
-
1202
- # channel_indices.append(idx)
1203
- # channel_indices = np.array(channel_indices)
1204
- # else:
1205
- # channel_indices = np.arange(len(required_channels))
1206
-
1207
1192
  return channel_indices
1208
1193
 
1209
1194
  def ConfigSectionMap(path,section):
@@ -2044,8 +2029,8 @@ def augmenter(x, y, flip=True, gauss_blur=True, noise_option=True, shift=True,
2044
2029
  if channel_extinction:
2045
2030
  assert extinction_probability <= 1.,'The extinction probability must be a number between 0 and 1.'
2046
2031
  channel_off = [np.random.random() < extinction_probability for i in range(x.shape[-1])]
2047
- if not np.all(channel_off):
2048
- x[:,:,np.array(channel_off, dtype=bool)] = 0.
2032
+ channel_off[0] = False
2033
+ x[:,:,np.array(channel_off, dtype=bool)] = 0.
2049
2034
 
2050
2035
  return x, y
2051
2036
 
@@ -2318,9 +2303,9 @@ def get_zenodo_files(cat=None):
2318
2303
  for f in all_files_short:
2319
2304
  if f.startswith('CP') or f.startswith('SD'):
2320
2305
  category = os.sep.join(['models','segmentation_generic'])
2321
- elif f.startswith('MCF7'):
2306
+ elif f.startswith('MCF7') or f.startswith('mcf7'):
2322
2307
  category = os.sep.join(['models','segmentation_targets'])
2323
- elif f.startswith('primNK'):
2308
+ elif f.startswith('primNK') or f.startswith('lymphocytes'):
2324
2309
  category = os.sep.join(['models','segmentation_effectors'])
2325
2310
  elif f.startswith('demo'):
2326
2311
  category = 'demos'
@@ -2362,9 +2347,7 @@ def download_zenodo_file(file, output_dir):
2362
2347
  if len(file_to_rename)>0 and not file_to_rename[0].endswith(os.sep) and not file.startswith('demo'):
2363
2348
  os.rename(file_to_rename[0], os.sep.join([output_dir,file,file]))
2364
2349
 
2365
- if file=="db_mcf7_nuclei_w_primary_NK":
2366
- os.rename(os.sep.join([output_dir,file.replace('db_','')]), os.sep.join([output_dir,file]))
2367
- if file=="db_primary_NK_w_mcf7":
2350
+ if file.startswith('db_'):
2368
2351
  os.rename(os.sep.join([output_dir,file.replace('db_','')]), os.sep.join([output_dir,file]))
2369
2352
  if file=='db-si-NucPI':
2370
2353
  os.rename(os.sep.join([output_dir,'db2-NucPI']), os.sep.join([output_dir,file]))
@@ -2476,4 +2459,77 @@ def step_function(t, t_shift, dt):
2476
2459
  array([0.26894142, 0.37754067, 0.5 , 0.62245933, 0.73105858, 0.81757448])
2477
2460
  """
2478
2461
 
2479
- return 1/(1+np.exp(-(t-t_shift)/dt))
2462
+ return 1/(1+np.exp(-(t-t_shift)/dt))
2463
+
2464
+
2465
+ def test_2samp_generic(data, feature=None, groupby_cols=None, method="ks_2samp", *args, **kwargs):
2466
+
2467
+ """
2468
+ Performs pairwise statistical tests between groups of data, comparing a specified feature using a chosen method.
2469
+
2470
+ The function applies two-sample statistical tests, such as the Kolmogorov-Smirnov (KS) test or Cliff's Delta,
2471
+ to compare distributions of a given feature across groups defined by `groupby_cols`. It returns the test results
2472
+ in a pivot table format with each group's pairwise comparison.
2473
+
2474
+ Parameters
2475
+ ----------
2476
+ data : pandas.DataFrame
2477
+ The input dataset containing the feature to be tested.
2478
+ feature : str
2479
+ The name of the column representing the feature to compare between groups.
2480
+ groupby_cols : list or str
2481
+ The column(s) used to group the data. These columns define the groups that will be compared pairwise.
2482
+ method : str, optional, default="ks_2samp"
2483
+ The statistical test to use. Options:
2484
+ - "ks_2samp": Two-sample Kolmogorov-Smirnov test (default).
2485
+ - "cliffs_delta": Cliff's Delta for effect size between two distributions.
2486
+ *args, **kwargs :
2487
+ Additional arguments and keyword arguments for the selected test method.
2488
+
2489
+ Returns
2490
+ -------
2491
+ pivot : pandas.DataFrame
2492
+ A pivot table containing the pairwise test results (p-values or effect sizes).
2493
+ The rows and columns represent the unique groups defined by `groupby_cols`,
2494
+ and the values represent the test result (e.g., p-values or effect sizes) between each group.
2495
+
2496
+ Notes
2497
+ -----
2498
+ - The function compares all unique pairwise combinations of the groups based on `groupby_cols`.
2499
+ - For the "ks_2samp" method, the test compares the distributions using the Kolmogorov-Smirnov test.
2500
+ - For the "cliffs_delta" method, the function calculates the effect size between two distributions.
2501
+ - The results are returned in a symmetric pivot table where each cell represents the test result for the corresponding group pair.
2502
+
2503
+ """
2504
+
2505
+
2506
+ assert groupby_cols is not None,"Please set a valid groupby_cols..."
2507
+ assert feature is not None,"Please set a feature to test..."
2508
+
2509
+ results = []
2510
+
2511
+ for lbl1,group1 in data.dropna(subset=feature).groupby(groupby_cols):
2512
+ for lbl2,group2 in data.dropna(subset=feature).groupby(groupby_cols):
2513
+
2514
+ dist1 = group1[feature].values
2515
+ dist2 = group2[feature].values
2516
+ if method=="ks_2samp":
2517
+ test = ks_2samp(list(dist1),list(dist2), alternative='less', mode='auto', *args, **kwargs)
2518
+ val = test.pvalue
2519
+ elif method=="cliffs_delta":
2520
+ test = cliffs_delta(list(dist1),list(dist2), *args, **kwargs)
2521
+ val = test[0]
2522
+
2523
+ results.append({"cdt1": lbl1, "cdt2": lbl2, "value": val})
2524
+
2525
+ results = pd.DataFrame(results)
2526
+ results['cdt1'] = results['cdt1'].astype(str)
2527
+ results['cdt2'] = results['cdt2'].astype(str)
2528
+
2529
+ pivot = results.pivot(index='cdt1', columns='cdt2', values='value')
2530
+ pivot.reset_index(inplace=True)
2531
+ pivot.columns.name = None
2532
+ pivot.set_index("cdt1",drop=True, inplace=True)
2533
+ pivot.index.name = None
2534
+
2535
+ return pivot
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: celldetective
3
- Version: 1.2.2.post2
3
+ Version: 1.3.0.post1
4
4
  Summary: description
5
5
  Home-page: http://github.com/remyeltorro/celldetective
6
6
  Author: Rémy Torro
@@ -38,6 +38,8 @@ Requires-Dist: matplotlib-scalebar
38
38
  Requires-Dist: numpy==1.26.4
39
39
  Requires-Dist: pytest
40
40
  Requires-Dist: pytest-qt
41
+ Requires-Dist: h5py
42
+ Requires-Dist: cliffs-delta
41
43
 
42
44
  # Celldetective
43
45
 
@@ -1,32 +1,33 @@
1
- celldetective/__init__.py,sha256=PH25g2_AZt7N5Jg1KB3YT9wFvfMr9lIb2WxYzmDqlX4,105
1
+ celldetective/__init__.py,sha256=bi3SGTMo6s2qQBsJAaKy-a4xaGcTQVW8zsqaiX5XKeY,139
2
2
  celldetective/__main__.py,sha256=_H9B620ntENFx9RBvlV6ybxpvtHzCbv5NnIPmDBr9Z0,1127
3
- celldetective/events.py,sha256=D07LyzBerq4QkXKRhMj0ZChzNkqBrW45E9TgBtEa3tk,4735
3
+ celldetective/_version.py,sha256=psRKPA5pfVLLl8tIZkft2nS2RjrlphliNDLiwS7_UEA,28
4
+ celldetective/events.py,sha256=hPnGSeQtQEwLM7Ks9_7AnuXgEVjQXD_LZeoayE4v7x0,4847
4
5
  celldetective/extra_properties.py,sha256=8DkxTvVs7gASsnnGurVZ3_zt6uR0pvvJhBKO2LC6hGk,5118
5
6
  celldetective/filters.py,sha256=b0qKwHor1fvNA_dHovP17nQz8EsW5YlyhT2TJnayn08,3615
6
- celldetective/io.py,sha256=Jld2Nt1cRZyJxUz2wdX-izrd0mp4DJ2P_AMwCDOLUfs,86273
7
- celldetective/measure.py,sha256=7bfCUdLfJbGmFWWwhu_C9-l1buj_-We7izBaFWTe4ok,54910
7
+ celldetective/io.py,sha256=erGKB0ALcLe5ffuo7pkuACDBC2DR-ZBmJHUcKfCLkrM,86442
8
+ celldetective/measure.py,sha256=S2aEhAAdwNk2p2d8rGG78MoN1g19zTUxYQhCQ-febQI,56328
8
9
  celldetective/neighborhood.py,sha256=GjF_fTmtcU8jq5XZT-DnDSp28VDTrsaHjIGJG7W2Ppk,52799
9
10
  celldetective/preprocessing.py,sha256=iV5or20s8XPJXQZDsWzis7OBaqzPDyAo_cwcDVDuX5A,38188
10
11
  celldetective/relative_measurements.py,sha256=qPHC6gtUaICNGKh6Qfh8y6NA4OUJauGcaj9_TUbrswg,24998
11
- celldetective/segmentation.py,sha256=H_6BH_RKaG6injUPZ3gQzQ112pMyzQ33u5GEpLE9dsQ,30426
12
+ celldetective/segmentation.py,sha256=NjAVaVpZufpJ-LIvBx5UFH6j5kjRKE6EVLjttDrqaqs,30826
12
13
  celldetective/signals.py,sha256=485axzJwE3xsSsN4AmBQlZ2at7uWu9QRg0XrUHvLBUE,120552
13
14
  celldetective/tracking.py,sha256=HGeOtfQ-nmpaea9_Q-sq2WcwZfdPXRH028JyFlt6eUs,37901
14
- celldetective/utils.py,sha256=yuPsRGsw2tYE1IApGulC83dtHOhsIhbts-46b6V83QA,86375
15
+ celldetective/utils.py,sha256=4Nf6jGMdd6kOcF3z0Q_3J8LLZ7Y3fOJKYUwGzUlzk3Q,88768
15
16
  celldetective/datasets/segmentation_annotations/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
17
  celldetective/datasets/signal_annotations/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
18
  celldetective/gui/InitWindow.py,sha256=M0v58BmOuZ05em2WSXHpDar3tp2AeS6pr44ZBtiYz-4,13683
18
19
  celldetective/gui/__init__.py,sha256=2_r2xfOj4_2xj0yBkCTIfzlF94AHKm-j6Pvpd7DddQc,989
19
- celldetective/gui/about.py,sha256=fed6nh-WwKy6bEbavy6L62P0CQB8VsOO0PajOjHsnFk,1694
20
+ celldetective/gui/about.py,sha256=FJZrj6C-p6uqp_3UaprKosuW-Sw9_HPNQAvFbis9Gdk,1749
20
21
  celldetective/gui/analyze_block.py,sha256=sat8RECEeZxlaconZZIxI0IrIjwJo121PcBXqJmA1-o,24756
21
22
  celldetective/gui/btrack_options.py,sha256=OrvbG5coZhLRk5jtXiLFJu34z1hWHN9kHkBiZ7XMZoI,39269
22
- celldetective/gui/classifier_widget.py,sha256=hyonoHikEkqEsxtE1PZ6cFAn72KcxfSIp8H8PlFPL1c,15822
23
+ celldetective/gui/classifier_widget.py,sha256=cjCuBGvNPI9OQeBeLlLI2h9mDUHHslWkJRjn4JIuVOw,16098
23
24
  celldetective/gui/configure_new_exp.py,sha256=Eyr-M4FH-4xrUJbIGNdKXAtXb_ULr8lCol26JSzXEww,20125
24
- celldetective/gui/control_panel.py,sha256=vU6dfjiO2nmDiY-qF2xCzcwDih6M87ItYTJOeOP51c8,19006
25
+ celldetective/gui/control_panel.py,sha256=JbS47IFeVHc1D2olWiUB_Lo9Bn20QJCPVwhXnRdlFec,18990
25
26
  celldetective/gui/generic_signal_plot.py,sha256=OzlFr2RxspkyxW1YIhl_c3q63RXAngMPouYPhEtk0S0,29509
26
- celldetective/gui/gui_utils.py,sha256=snYUefDEFpIP8RlsNG4QhfI0rLiVE9_t1E8Q7dMIj4k,27747
27
+ celldetective/gui/gui_utils.py,sha256=afqJTeVyMa49QEbSmT0hAiXGd7EiKzckOD5tMvUr-aY,27901
27
28
  celldetective/gui/json_readers.py,sha256=Su3angSobroeGrrumGgQcs3Cr_9l9p52-Hfm3qneVcI,3664
28
29
  celldetective/gui/layouts.py,sha256=feeAYh7I21ZgH-x4I7lg2DAvz5PBm71D7MovCrtb9QE,47325
29
- celldetective/gui/measurement_options.py,sha256=fDm8mlak8o9jC8OHhmou9kAmrVY8fCZ8ZKZ0bimhuPo,47133
30
+ celldetective/gui/measurement_options.py,sha256=0CAxM61NqfWVsBaHD1cuC04kMER96-Tgom1p8G5X7Qg,39249
30
31
  celldetective/gui/neighborhood_options.py,sha256=BvWwsIX1KWogUgHWRZptqY3ZRmH1aj7r8tiLmbRFhW4,19783
31
32
  celldetective/gui/plot_measurements.py,sha256=SBFkY3542hW4H_vllOCMxMOgBz09KUE2FLhhgI8avXk,51024
32
33
  celldetective/gui/plot_signals_ui.py,sha256=dQINAOyOmAOHMfmjfCsx1hJ7HGeCgNCq8kESuADbQqo,15864
@@ -34,12 +35,12 @@ celldetective/gui/process_block.py,sha256=PdgKKEfr-GFad3P1y0n9LB_OaIBvuBuaQdBRtz
34
35
  celldetective/gui/retrain_segmentation_model_options.py,sha256=eGGrimwmNfJXRPRpZ6NZ74TWx6TK70HoNRHnJl1_8XQ,22292
35
36
  celldetective/gui/retrain_signal_model_options.py,sha256=XigNdGlNu3KWB_MYBcKQhfXjcWwVZNMmu0qmxNoo14E,21919
36
37
  celldetective/gui/seg_model_loader.py,sha256=vWvPMU6nkTiQfI-x2WjQHrdJGFdV4a4Ne-4YIOq_YZ8,18153
37
- celldetective/gui/signal_annotator.py,sha256=5Ho7o6lze3BWUbCKJ-53Jh4S46QlTmUq237FAAOfECA,87069
38
+ celldetective/gui/signal_annotator.py,sha256=z205XhTZjKPo9L4lzt-g-uLiu9vk6V1w5zUlxu3bWqQ,87379
38
39
  celldetective/gui/signal_annotator2.py,sha256=Y43JSCg3bO_QL7zsqdeQ-FY8TNq_5WiV1cHO-knK0QE,109375
39
40
  celldetective/gui/signal_annotator_options.py,sha256=ztFFgA70SJ0QkntxYGsgDNCvSuSR5GjF7_J6pYVYc1g,11020
40
41
  celldetective/gui/styles.py,sha256=fup0_U1Zk0IJAjyruHde_r-X7d7cTMcrpPLPl-HuKAM,4820
41
42
  celldetective/gui/survival_ui.py,sha256=tzvtI0eC0bgd7Lfm20HqU7rfCJ60gy9a_Sc9cZLSKhs,9439
42
- celldetective/gui/tableUI.py,sha256=9yJ4CjeNAQoYdHXfsVvD0qr_IdYWuQwIBhvfU3QoNtc,40602
43
+ celldetective/gui/tableUI.py,sha256=sHmXjRhMYjYY4qCrUyMKZf4O-PorvJuMzHbVwshSNVs,46167
43
44
  celldetective/gui/thresholds_gui.py,sha256=t1hTDdaJTJWHBt9vtRCE4B1TsVHhobQwCpKfntVgaQI,50510
44
45
  celldetective/gui/viewers.py,sha256=mCyE9DaUX2rGq65oYEwyEfNtEUPrHdoFNg2MRp1kXs4,27701
45
46
  celldetective/gui/help/DL-segmentation-strategy.json,sha256=59jVtn8pECbCqPQwJifgViVYTF1AxLQDIkNJMS7CJuk,1143
@@ -62,7 +63,7 @@ celldetective/icons/splash0.png,sha256=qVXsrYUinm5g6-vbHcqwyjh8SIqs9lEqPWnPa1Wij
62
63
  celldetective/icons/survival2.png,sha256=8zsualD7d9VPAecoFA4Om9TFARErqpJzMg6U7XANXf4,4479
63
64
  celldetective/icons/vignette_signals2.png,sha256=hsVOdQDpEfMGM45aaSeacEm3lvxbquRKKYutiS9qoS0,20743
64
65
  celldetective/icons/vignette_signals2.svg,sha256=muGNcQudV1jG-bmFd9FwV-Wb8PcrRV5osdZ7pHR7Ekk,5947
65
- celldetective/links/zenodo.json,sha256=7WKRuZY7MHTR-IChWBbU0i47H_479NtlxsCGaJn9-xM,22728
66
+ celldetective/links/zenodo.json,sha256=qxbRAWRRXgeM4GMPhcvuRFWviI_W0pwovQOq_k5I6Uw,30216
66
67
  celldetective/models/pair_signal_detection/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
68
  celldetective/models/segmentation_effectors/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
69
  celldetective/models/segmentation_generic/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -87,13 +88,13 @@ tests/test_measure.py,sha256=FEUAs1rVHylvIvubCb0bJDNGZLVmkgXNgI3NaGQ1dA8,4542
87
88
  tests/test_neighborhood.py,sha256=gk5FmoI7ANEczUtNXYRxc48KzkfYzemwS_eYaLq4_NI,2093
88
89
  tests/test_preprocessing.py,sha256=FI-Wk-kc4wWmOQg_NLCUIZC1oti396wr5cC-BauBai0,1436
89
90
  tests/test_qt.py,sha256=eYqOoff-vfvZAZM6H_IY19IqK7qzyETcyj54f9T0bQA,3906
90
- tests/test_segmentation.py,sha256=_HB8CCq-Ci6amf0xAmDIUuwtBUU_EGpgqLvcvSHrGug,3427
91
+ tests/test_segmentation.py,sha256=k1b_zIZdlytEdJcHjAUQEO3gTBAHtv5WvrwQN2xD4kc,3470
91
92
  tests/test_signals.py,sha256=No4cah6KxplhDcKXnU8RrA7eDla4hWw6ccf7xGnBokU,3599
92
93
  tests/test_tracking.py,sha256=8hebWSqEIuttD1ABn-6dKCT7EXKRR7-4RwyFWi1WPFo,8800
93
94
  tests/test_utils.py,sha256=NKRCAC1d89aBK5cWjTb7-pInYow901RrT-uBlIdz4KI,3692
94
- celldetective-1.2.2.post2.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
95
- celldetective-1.2.2.post2.dist-info/METADATA,sha256=WT8GY_72_xK3YgqdZ97FwTWh857CGSzzNPJLKBJRIhI,9923
96
- celldetective-1.2.2.post2.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
97
- celldetective-1.2.2.post2.dist-info/entry_points.txt,sha256=2NU6_EOByvPxqBbCvjwxlVlvnQreqZ3BKRCVIKEv3dg,62
98
- celldetective-1.2.2.post2.dist-info/top_level.txt,sha256=6rsIKKfGMKgud7HPuATcpq6EhdXwcg_yknBVWn9x4C4,20
99
- celldetective-1.2.2.post2.dist-info/RECORD,,
95
+ celldetective-1.3.0.post1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
96
+ celldetective-1.3.0.post1.dist-info/METADATA,sha256=QzPTXc4_K4xgHDJ60xC7CaHbejQ9wjSXGwOEGj1LYrc,9971
97
+ celldetective-1.3.0.post1.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
98
+ celldetective-1.3.0.post1.dist-info/entry_points.txt,sha256=2NU6_EOByvPxqBbCvjwxlVlvnQreqZ3BKRCVIKEv3dg,62
99
+ celldetective-1.3.0.post1.dist-info/top_level.txt,sha256=6rsIKKfGMKgud7HPuATcpq6EhdXwcg_yknBVWn9x4C4,20
100
+ celldetective-1.3.0.post1.dist-info/RECORD,,
@@ -21,11 +21,12 @@ class TestDLMCF7Segmentation(unittest.TestCase):
21
21
  with open(TEST_CONFIG_FILENAME) as config_file:
22
22
  self.config = json.load(config_file)
23
23
  self.channels = self.config['channels']
24
+ print(f'{self.channels=}')
24
25
  self.spatial_calibration = self.config['spatial_calibration']
25
26
 
26
27
  def test_correct_segmentation_with_multimodal_model(self):
27
28
 
28
- labels = segment(self.stack, "MCF7_bf_pi_cfse_h", channels=self.channels, spatial_calibration=self.spatial_calibration, view_on_napari=False,
29
+ labels = segment(self.stack, "mcf7_nuc_multimodal", channels=self.channels, spatial_calibration=self.spatial_calibration, view_on_napari=False,
29
30
  use_gpu=False)
30
31
  np.testing.assert_array_equal(labels[0], labels[1])
31
32
 
@@ -39,11 +40,11 @@ class TestDLMCF7Segmentation(unittest.TestCase):
39
40
  m.update_state(self.binary_label_true, label_binary)
40
41
  score = m.result().numpy()
41
42
 
42
- self.assertGreater(score,0.9)
43
+ self.assertGreater(score,0.85)
43
44
 
44
45
  def test_correct_segmentation_with_transferred_model(self):
45
46
 
46
- labels = segment(self.stack, "MCF7_h_versatile", channels=self.channels, spatial_calibration=self.spatial_calibration, view_on_napari=False,
47
+ labels = segment(self.stack, "mcf7_nuc_stardist_transfer", channels=self.channels, spatial_calibration=self.spatial_calibration, view_on_napari=False,
47
48
  use_gpu=True)
48
49
  np.testing.assert_array_equal(labels[0], labels[1])
49
50
 
@@ -57,7 +58,7 @@ class TestDLMCF7Segmentation(unittest.TestCase):
57
58
  m.update_state(self.binary_label_true, label_binary)
58
59
  score = m.result().numpy()
59
60
 
60
- self.assertGreater(score,0.9)
61
+ self.assertGreater(score,0.85)
61
62
 
62
63
 
63
64
  class TestThresholdMCF7Segmentation(unittest.TestCase):