celldetective 1.3.9.post2__py3-none-any.whl → 1.3.9.post4__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/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.3.9.post2"
1
+ __version__ = "1.3.9.post4"
@@ -29,6 +29,7 @@ from celldetective.utils import interpolate_nan, contour_of_instance_segmentatio
29
29
  import skimage.measure as skm
30
30
  from stardist import fill_label_holes
31
31
  from celldetective.segmentation import segment_frame_from_thresholds
32
+ from sklearn.metrics import r2_score
32
33
 
33
34
 
34
35
  # def area_detected_in_ricm(regionmask, intensity_image, target_channel='adhesion_channel'):
@@ -65,7 +66,7 @@ from celldetective.segmentation import segment_frame_from_thresholds
65
66
 
66
67
  # return np.sum(lbl)
67
68
 
68
- def fraction_of_area_detected_in_ricm(regionmask, intensity_image, target_channel='adhesion_channel'):
69
+ def fraction_of_area_detected_in_intensity(regionmask, intensity_image, target_channel='adhesion_channel'):
69
70
 
70
71
  instructions = {
71
72
  "thresholds": [
@@ -94,7 +95,7 @@ def fraction_of_area_detected_in_ricm(regionmask, intensity_image, target_channe
94
95
 
95
96
  return float(np.sum(lbl)) / float(np.sum(regionmask))
96
97
 
97
- def area_detected_in_ricm(regionmask, intensity_image, target_channel='adhesion_channel'):
98
+ def area_detected_in_intensity(regionmask, intensity_image, target_channel='adhesion_channel'):
98
99
 
99
100
  instructions = {
100
101
  "thresholds": [
@@ -124,7 +125,7 @@ def area_detected_in_ricm(regionmask, intensity_image, target_channel='adhesion_
124
125
  return float(np.sum(lbl))
125
126
 
126
127
 
127
- def area_dark(regionmask, intensity_image, target_channel='adhesion_channel', fill_holes=True): #, target_channel='adhesion_channel'
128
+ def area_dark_intensity(regionmask, intensity_image, target_channel='adhesion_channel', fill_holes=True): #, target_channel='adhesion_channel'
128
129
 
129
130
  subregion = (intensity_image < 0.95)*regionmask # under one, under 0.8, under 0.6, whatever value!
130
131
  if fill_holes:
@@ -135,7 +136,7 @@ def area_dark(regionmask, intensity_image, target_channel='adhesion_channel', fi
135
136
  return float(np.sum(subregion))
136
137
 
137
138
 
138
- def fraction_of_area_dark(regionmask, intensity_image, target_channel='adhesion_channel', fill_holes=True): #, target_channel='adhesion_channel'
139
+ def fraction_of_area_dark_intensity(regionmask, intensity_image, target_channel='adhesion_channel', fill_holes=True): #, target_channel='adhesion_channel'
139
140
 
140
141
  subregion = (intensity_image < 0.95)*regionmask # under one, under 0.8, under 0.6, whatever value!
141
142
  if fill_holes:
@@ -180,62 +181,51 @@ def intensity_nanmean(regionmask, intensity_image):
180
181
  else:
181
182
  return np.nanmean(intensity_image[regionmask])
182
183
 
183
- def intensity_centre_of_mass_displacement(regionmask, intensity_image):
184
+ def intensity_center_of_mass_displacement(regionmask, intensity_image):
184
185
 
185
- intensity_image = interpolate_nan(intensity_image.copy())
186
+ if np.any(intensity_image!=intensity_image):
187
+ intensity_image = interpolate_nan(intensity_image.copy())
186
188
 
187
- y, x = np.mgrid[:regionmask.shape[0], :regionmask.shape[1]]
188
- xtemp = x.copy()
189
- ytemp = y.copy()
190
- intensity_weighted_center = center_of_mass(intensity_image, regionmask)
191
- centroid_x = intensity_weighted_center[1]
192
- centroid_y = intensity_weighted_center[0]
189
+ if not np.all(intensity_image.flatten()==0):
190
+
191
+ y, x = np.mgrid[:regionmask.shape[0], :regionmask.shape[1]]
192
+ xtemp = x.copy()
193
+ ytemp = y.copy()
193
194
 
194
- #centroid_x = np.sum(xtemp * intensity_image) / np.sum(intensity_image)
195
- geometric_centroid_x = np.sum(xtemp * regionmask) / np.sum(regionmask)
196
- geometric_centroid_y = np.sum(ytemp * regionmask) / np.sum(regionmask)
197
- try:
198
- distance = euclidean(np.array((geometric_centroid_y, geometric_centroid_x)), np.array((centroid_y, centroid_x)))
199
- except:
200
- distance = np.nan
195
+ intensity_image[intensity_image<=0.] = 0. #important to clip as negative intensities misbehave with center of mass
196
+ intensity_weighted_center = center_of_mass(intensity_image*regionmask, regionmask, 1)
197
+ centroid_x = intensity_weighted_center[1]
198
+ centroid_y = intensity_weighted_center[0]
201
199
 
202
- delta_x = geometric_centroid_x - centroid_x
203
- delta_y = geometric_centroid_y - centroid_y
204
- direction_arctan = np.arctan2(delta_y, delta_x) * 180 / np.pi
205
- if direction_arctan < 0:
206
- direction_arctan += 360
200
+ geometric_centroid_x = np.sum(xtemp * regionmask) / np.sum(regionmask)
201
+ geometric_centroid_y = np.sum(ytemp * regionmask) / np.sum(regionmask)
202
+ distance = np.sqrt((geometric_centroid_y - centroid_y)**2 + (geometric_centroid_x - centroid_x)**2)
207
203
 
208
- return distance, direction_arctan, centroid_x - geometric_centroid_x, centroid_y - geometric_centroid_y
204
+ delta_x = geometric_centroid_x - centroid_x
205
+ delta_y = geometric_centroid_y - centroid_y
206
+ direction_arctan = np.arctan2(delta_y, delta_x) * 180 / np.pi
209
207
 
210
- def intensity_radial_gradient(regionmask, intensity_image):
208
+ return distance, direction_arctan, centroid_x - geometric_centroid_x, centroid_y - geometric_centroid_y
211
209
 
212
- try:
213
- warnings.filterwarnings('ignore', message="Polyfit may be poorly conditioned")
214
- cell_mask = regionmask.copy()
215
- intensity = intensity_image.copy()
216
- y = intensity[cell_mask].flatten()
217
- x = distance_transform_edt(cell_mask)
218
- x = x[cell_mask].flatten()
219
- params = np.polyfit(x, y, 1)
220
- line = np.poly1d(params)
210
+ else:
211
+ return np.nan, np.nan, np.nan, np.nan
221
212
 
222
- return line.coefficients[0], line.coefficients[1]
223
- except Exception as e:
224
- print(e)
225
- return np.nan, np.nan
226
213
 
214
+ def intensity_center_of_mass_displacement_edge(regionmask, intensity_image):
227
215
 
228
- def intensity_centre_of_mass_displacement_edge(regionmask, intensity_image):
229
-
230
- intensity_image = interpolate_nan(intensity_image.copy())
231
- edge_mask = contour_of_instance_segmentation(regionmask, 3)
216
+ if np.any(intensity_image!=intensity_image):
217
+ intensity_image = interpolate_nan(intensity_image.copy())
232
218
 
233
- if np.sum(edge_mask)>0:
219
+ edge_mask = contour_of_instance_segmentation(regionmask, 3)
220
+
221
+ if not np.all(intensity_image.flatten()==0) and np.sum(edge_mask)>0:
234
222
 
235
223
  y, x = np.mgrid[:edge_mask.shape[0], :edge_mask.shape[1]]
236
224
  xtemp = x.copy()
237
225
  ytemp = y.copy()
238
- intensity_weighted_center = center_of_mass(intensity_image, edge_mask)
226
+
227
+ intensity_image[intensity_image<=0.] = 0. #important to clip as negative intensities misbehave with center of mass
228
+ intensity_weighted_center = center_of_mass(intensity_image*edge_mask, edge_mask, 1)
239
229
  centroid_x = intensity_weighted_center[1]
240
230
  centroid_y = intensity_weighted_center[0]
241
231
 
@@ -243,17 +233,41 @@ def intensity_centre_of_mass_displacement_edge(regionmask, intensity_image):
243
233
  geometric_centroid_x = np.sum(xtemp * regionmask) / np.sum(regionmask)
244
234
  geometric_centroid_y = np.sum(ytemp * regionmask) / np.sum(regionmask)
245
235
 
246
- try:
247
- distance = euclidean(np.array((geometric_centroid_y, geometric_centroid_x)), np.array((centroid_y, centroid_x)))
248
- except:
249
- distance = np.nan
236
+ distance = np.sqrt((geometric_centroid_y - centroid_y)**2 + (geometric_centroid_x - centroid_x)**2)
250
237
 
251
238
  delta_x = geometric_centroid_x - centroid_x
252
239
  delta_y = geometric_centroid_y - centroid_y
253
240
  direction_arctan = np.arctan2(delta_y, delta_x) * 180 / np.pi
254
- if direction_arctan < 0:
255
- direction_arctan += 360
256
241
 
257
242
  return distance, direction_arctan, centroid_x - geometric_centroid_x, centroid_y - geometric_centroid_y
258
243
  else:
259
- return np.nan, np.nan, np.nan, np.nan
244
+ return np.nan, np.nan, np.nan, np.nan
245
+
246
+
247
+ def intensity_radial_gradient(regionmask, intensity_image):
248
+
249
+ """
250
+ Determine if intensities are following a linear gradient from center to edge of the cell.
251
+ """
252
+
253
+ if np.any(intensity_image!=intensity_image):
254
+ intensity_image = interpolate_nan(intensity_image.copy())
255
+
256
+ # try:
257
+ warnings.filterwarnings('ignore', message="Polyfit may be poorly conditioned")
258
+
259
+ # intensities
260
+ y = intensity_image[regionmask].flatten()
261
+
262
+ # distance to edge
263
+ x = distance_transform_edt(regionmask.copy())
264
+ x = x[regionmask].flatten()
265
+ x = max(x) - x # origin at center of cells
266
+
267
+ params = np.polyfit(x, y, 1)
268
+ line = np.poly1d(params)
269
+ # coef > 0 --> more signal at edge than center, coef < 0 --> more signal at center than edge
270
+
271
+ r2 = r2_score(y, line(x))
272
+
273
+ return line.coefficients[0], line.coefficients[1], r2
@@ -365,7 +365,9 @@ class ClassifierWidget(QWidget, Styles):
365
365
  except Exception as e:
366
366
  msgBox = QMessageBox()
367
367
  msgBox.setIcon(QMessageBox.Warning)
368
- msgBox.setText(f"The query could not be understood. No filtering was applied. {e}")
368
+ link = "https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.query.html"
369
+ msg = "The query could not be understood. Please write a valid query following <a href='%s'>the documentation</a>. Wrap features in backticks (e.g. `feature` > 1) to facilitate query interpretation. " % link
370
+ msgBox.setText(msg)
369
371
  msgBox.setWindowTitle("Warning")
370
372
  msgBox.setStandardButtons(QMessageBox.Ok)
371
373
  returnValue = msgBox.exec()
@@ -848,7 +848,7 @@ class ProcessPanel(QFrame, Styles):
848
848
  if os.path.exists(os.sep.join([self.pos, 'output', 'tables', f'trajectories_{self.mode}.csv'])) and not self.parent_window.position_list.isMultipleSelection():
849
849
  msgBox = QMessageBox()
850
850
  msgBox.setIcon(QMessageBox.Question)
851
- msgBox.setText("A trajectory set already exists. Previously annotated data for\nthis position will be lost. Do you want to proceed?")
851
+ msgBox.setText("A measurement table already exists. Previously annotated data for\nthis position will be lost. Do you want to proceed?")
852
852
  msgBox.setWindowTitle("Info")
853
853
  msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
854
854
  returnValue = msgBox.exec()
@@ -196,7 +196,7 @@ class MeasurementProcess(Process):
196
196
  print('Previous table detected...')
197
197
  self.trajectories = pd.read_csv(self.trajectories)
198
198
  if 'TRACK_ID' not in list(self.trajectories.columns):
199
- print('Non-tracked cells detected...')
199
+ print('Static measurements detected...')
200
200
  self.do_iso_intensities = False
201
201
  self.intensity_measurement_radii = None
202
202
  if self.clear_previous:
@@ -206,7 +206,7 @@ class MeasurementProcess(Process):
206
206
  self.features += ['centroid']
207
207
  self.column_labels.update({'track': 'ID'})
208
208
  else:
209
- print('Tracked cells detected...')
209
+ print('Time series detected...')
210
210
  if self.clear_previous:
211
211
  print('TRACK_ID found... Clear previous measurements...')
212
212
  self.trajectories = remove_trajectory_measurements(self.trajectories, self.column_labels)
@@ -1106,7 +1106,7 @@ class ThresholdNormalisation(ThresholdConfigWizard):
1106
1106
  if len_movie_auto is not None:
1107
1107
  self.len_movie = len_movie_auto
1108
1108
  exp_config = self.exp_dir + "config.ini"
1109
- self.channel_names, self.channels = extract_experiment_channels(exp_config)
1109
+ self.channel_names, self.channels = extract_experiment_channels(self.exp_dir)
1110
1110
  self.channel_names = np.array(self.channel_names)
1111
1111
  self.channels = np.array(self.channels)
1112
1112
  self.nbr_channels = len(self.channels)
celldetective/io.py CHANGED
@@ -210,19 +210,23 @@ def collect_experiment_metadata(pos_path=None, well_path=None):
210
210
  pos_name = extract_position_name(pos_path)
211
211
  else:
212
212
  pos_name = 0
213
- concentrations = get_experiment_concentrations(experiment, dtype=float)
214
- cell_types = get_experiment_cell_types(experiment)
215
- antibodies = get_experiment_antibodies(experiment)
216
- pharmaceutical_agents = get_experiment_pharmaceutical_agents(experiment)
217
-
218
- dico = {"pos_path": pos_path, "position": pos_path, "pos_name": pos_name, "well_path": well_path, "well_name": well_name, "well_nbr": well_nbr, "experiment": experiment, "antibody": antibodies[idx], "concentration": concentrations[idx], "cell_type": cell_types[idx], "pharmaceutical_agent": pharmaceutical_agents[idx]}
213
+
214
+ dico = {"pos_path": pos_path, "position": pos_path, "pos_name": pos_name, "well_path": well_path, "well_name": well_name, "well_nbr": well_nbr, "experiment": experiment}
219
215
 
220
216
  meta = get_experiment_metadata(experiment) # None or dict of metadata
221
217
  if meta is not None:
222
218
  keys = list(meta.keys())
223
219
  for k in keys:
224
220
  dico.update({k: meta[k]})
225
-
221
+
222
+ labels = get_experiment_labels(experiment)
223
+ for k in list(labels.keys()):
224
+ values = labels[k]
225
+ try:
226
+ dico.update({k: values[idx]})
227
+ except Exception as e:
228
+ print(f"{e=}")
229
+
226
230
  return dico
227
231
 
228
232
 
@@ -2498,24 +2502,34 @@ def control_segmentation_napari(position, prefix='Aligned', population="target",
2498
2502
  config = PurePath(expfolder, Path("config.ini"))
2499
2503
  expfolder = str(expfolder)
2500
2504
  exp_name = os.path.split(expfolder)[-1]
2501
- print(exp_name)
2502
2505
 
2503
2506
  wells = get_experiment_wells(expfolder)
2504
2507
  well_idx = list(wells).index(str(parent1)+os.sep)
2505
- ab = get_experiment_antibodies(expfolder)[well_idx]
2506
- conc = get_experiment_concentrations(expfolder)[well_idx]
2507
- ct = get_experiment_cell_types(expfolder)[well_idx]
2508
- pa = get_experiment_pharmaceutical_agents(expfolder)[well_idx]
2509
2508
 
2509
+ label_info = get_experiment_labels(expfolder)
2510
+ metadata_info = get_experiment_metadata(expfolder)
2511
+
2512
+ info = {}
2513
+ for k in list(label_info.keys()):
2514
+ values = label_info[k]
2515
+ try:
2516
+ info.update({k: values[well_idx]})
2517
+ except Exception as e:
2518
+ print(f"{e=}")
2519
+
2520
+ if metadata_info is not None:
2521
+ keys = list(metadata_info.keys())
2522
+ for k in keys:
2523
+ info.update({k: metadata_info[k]})
2510
2524
 
2511
2525
  spatial_calibration = float(ConfigSectionMap(config,"MovieSettings")["pxtoum"])
2512
- channel_names, channel_indices = extract_experiment_channels(config)
2526
+ channel_names, channel_indices = extract_experiment_channels(expfolder)
2513
2527
 
2514
2528
  annotation_folder = expfolder + os.sep + f'annotations_{population}' + os.sep
2515
2529
  if not os.path.exists(annotation_folder):
2516
2530
  os.mkdir(annotation_folder)
2517
2531
 
2518
- print('exporting!')
2532
+ print('Exporting!')
2519
2533
  t = viewer.dims.current_step[0]
2520
2534
  labels_layer = viewer.layers['segmentation'].data[t] # at current time
2521
2535
 
@@ -2578,11 +2592,14 @@ def control_segmentation_napari(position, prefix='Aligned', population="target",
2578
2592
 
2579
2593
  save_tiff_imagej_compatible(annotation_folder + f"{exp_name}_{position.split(os.sep)[-2]}_{str(t).zfill(4)}_roi_{xmin}_{xmax}_{ymin}_{ymax}_labelled.tif", lab, axes='YX')
2580
2594
  save_tiff_imagej_compatible(annotation_folder + f"{exp_name}_{position.split(os.sep)[-2]}_{str(t).zfill(4)}_roi_{xmin}_{xmax}_{ymin}_{ymax}.tif", multichannel, axes='CYX')
2581
- info = {"spatial_calibration": spatial_calibration, "channels": list(channel_names), 'cell_type': ct, 'antibody': ab, 'concentration': conc, 'pharmaceutical_agent': pa}
2595
+
2596
+ info.update({"spatial_calibration": spatial_calibration, "channels": list(channel_names), 'frame': t})
2597
+
2582
2598
  info_name = annotation_folder + f"{exp_name}_{position.split(os.sep)[-2]}_{str(t).zfill(4)}_roi_{xmin}_{xmax}_{ymin}_{ymax}.json"
2583
2599
  with open(info_name, 'w') as f:
2584
2600
  json.dump(info, f, indent=4)
2585
2601
 
2602
+
2586
2603
  if fov_export:
2587
2604
  frame = viewer.layers['Image'].data[t]
2588
2605
  multichannel = [frame]
@@ -2595,11 +2612,14 @@ def control_segmentation_napari(position, prefix='Aligned', population="target",
2595
2612
  multichannel = np.array(multichannel)
2596
2613
  save_tiff_imagej_compatible(annotation_folder + f"{exp_name}_{position.split(os.sep)[-2]}_{str(t).zfill(4)}_labelled.tif", labels_layer, axes='YX')
2597
2614
  save_tiff_imagej_compatible(annotation_folder + f"{exp_name}_{position.split(os.sep)[-2]}_{str(t).zfill(4)}.tif", multichannel, axes='CYX')
2598
- info = {"spatial_calibration": spatial_calibration, "channels": list(channel_names), 'cell_type': ct, 'antibody': ab, 'concentration': conc, 'pharmaceutical_agent': pa}
2615
+
2616
+ info.update({"spatial_calibration": spatial_calibration, "channels": list(channel_names), 'frame': t})
2617
+
2599
2618
  info_name = annotation_folder + f"{exp_name}_{position.split(os.sep)[-2]}_{str(t).zfill(4)}.json"
2600
2619
  with open(info_name, 'w') as f:
2601
2620
  json.dump(info, f, indent=4)
2602
- print('Done.')
2621
+
2622
+ print('Done.')
2603
2623
 
2604
2624
  @magicgui(call_button='Save the modified labels')
2605
2625
  def save_widget():
@@ -101,12 +101,28 @@ class CustomRegionProps(RegionProperties):
101
101
  arg_dict = dict(inspect.signature(func).parameters)
102
102
  if self.channel_names is not None and 'target_channel' in arg_dict:
103
103
  multichannel_list = [np.nan for i in range(self.image_intensity.shape[-1])]
104
+ len_output = 1
104
105
  default_channel = arg_dict['target_channel']._default
106
+
105
107
  if default_channel in self.channel_names:
108
+
106
109
  idx = self.channel_names.index(default_channel)
107
- multichannel_list[idx] = func(self.image, self.image_intensity[..., idx])
110
+ res = func(self.image, self.image_intensity[..., idx])
111
+ if isinstance(res, tuple):
112
+ len_output = len(res)
113
+ else:
114
+ len_output = 1
115
+
116
+ if len_output > 1:
117
+ multichannel_list = [[np.nan]*len_output for c in range(len(self.channel_names))]
118
+ multichannel_list[idx] = res
119
+ else:
120
+ multichannel_list = [np.nan for c in range(len(self.channel_names))]
121
+ multichannel_list[idx] = res
122
+
108
123
  else:
109
124
  print(f'Warning... Channel required by custom measurement ({default_channel}) could not be found in your data...')
125
+
110
126
  return np.stack(multichannel_list, axis=-1)
111
127
  else:
112
128
  multichannel_list = [
@@ -59,7 +59,7 @@ movie_prefix = ConfigSectionMap(config,"MovieSettings")["movie_prefix"]
59
59
  spatial_calibration = float(ConfigSectionMap(config,"MovieSettings")["pxtoum"])
60
60
  time_calibration = float(ConfigSectionMap(config,"MovieSettings")["frametomin"])
61
61
  len_movie = float(ConfigSectionMap(config,"MovieSettings")["len_movie"])
62
- channel_names, channel_indices = extract_experiment_channels(config)
62
+ channel_names, channel_indices = extract_experiment_channels(expfolder)
63
63
  nbr_channels = len(channel_names)
64
64
 
65
65
  # from tracking instructions, fetch btrack config, features, haralick, clean_traj, idea: fetch custom timeline?
@@ -72,7 +72,7 @@ threshold_instructions.update({'target_channel': channel_indices[0]})
72
72
 
73
73
  movie_prefix = ConfigSectionMap(config,"MovieSettings")["movie_prefix"]
74
74
  len_movie = float(ConfigSectionMap(config,"MovieSettings")["len_movie"])
75
- channel_names, channel_indices = extract_experiment_channels(config)
75
+ channel_names, channel_indices = extract_experiment_channels(expfolder)
76
76
  threshold_instructions.update({'channel_names': channel_names})
77
77
 
78
78
  # Try to find the file
@@ -72,7 +72,7 @@ len_movie = float(ConfigSectionMap(config,"MovieSettings")["len_movie"])
72
72
  shape_x = int(ConfigSectionMap(config,"MovieSettings")["shape_x"])
73
73
  shape_y = int(ConfigSectionMap(config,"MovieSettings")["shape_y"])
74
74
 
75
- channel_names, channel_indices = extract_experiment_channels(config)
75
+ channel_names, channel_indices = extract_experiment_channels(expfolder)
76
76
  nbr_channels = len(channel_names)
77
77
 
78
78
  # from tracking instructions, fetch btrack config, features, haralick, clean_traj, idea: fetch custom timeline?
celldetective/utils.py CHANGED
@@ -1127,11 +1127,9 @@ def mask_edges(binary_mask, border_size):
1127
1127
  return binary_mask
1128
1128
 
1129
1129
  def demangle_column_name(name):
1130
- if name.startswith("BACKTICK_QUOTED_STRING_") and not '_MINUS_' in name:
1130
+ if name.startswith("BACKTICK_QUOTED_STRING_"):
1131
1131
  # Unquote backtick-quoted string.
1132
- return name[len("BACKTICK_QUOTED_STRING_"):].replace("_DOT_", ".").replace("_SLASH_", "/")
1133
- elif name.startswith("BACKTICK_QUOTED_STRING_") and '_MINUS_' in name:
1134
- return name[len("BACKTICK_QUOTED_STRING_"):].replace("_DOT_", ".").replace("_SLASH_", "/").replace('_MINUS_','-')
1132
+ return name[len("BACKTICK_QUOTED_STRING_"):].replace("_DOT_", ".").replace("_SLASH_", "/").replace('_MINUS_','-').replace('_PLUS_','+').replace('_PERCENT_','%').replace('_STAR_','*').replace('_LPAR_','(').replace('_RPAR_',')').replace('_AMPER_','&')
1135
1133
  return name
1136
1134
 
1137
1135
  def extract_cols_from_query(query: str):
@@ -1250,124 +1248,102 @@ def rename_intensity_column(df, channels):
1250
1248
  # Rename the intensity columns in the DataFrame based on the provided channel names.
1251
1249
 
1252
1250
  """
1253
-
1251
+
1254
1252
  channel_names = np.array(channels)
1255
1253
  channel_indices = np.arange(len(channel_names),dtype=int)
1254
+ intensity_cols = [s for s in list(df.columns) if 'intensity' in s]
1255
+
1256
+ to_rename = {}
1256
1257
 
1257
- if np.any(['intensity' in c for c in list(df.columns)]):
1258
-
1259
- intensity_indices = [s.startswith('intensity') for s in df.columns]
1260
- intensity_columns = df.columns[intensity_indices]
1261
-
1262
- if len(channel_names) >= 1:
1263
- to_rename = {}
1264
- for k in range(len(intensity_columns)):
1265
-
1266
- sections = np.array(re.split('-|_', intensity_columns[k]))
1267
- test_digit = np.array([s.isdigit() for s in sections])
1268
- index = int(sections[np.where(test_digit)[0]][-1])
1258
+ for k in range(len(intensity_cols)):
1259
+
1260
+ # identify if digit in section
1261
+ sections = np.array(re.split('-|_', intensity_cols[k]))
1262
+ test_digit = np.array([False for s in sections])
1263
+ for j,s in enumerate(sections):
1264
+ if s.isdigit():
1265
+ if int(s)<len(channel_names):
1266
+ test_digit[j] = True
1267
+
1268
+ if np.any(test_digit):
1269
+ index = int(sections[np.where(test_digit)[0]][-1])
1270
+ else:
1271
+ print(f'No valid channel index found for {intensity_cols[k]}... Skipping the renaming for {intensity_cols[k]}...')
1272
+ continue
1273
+
1274
+ channel_name = channel_names[np.where(channel_indices==index)[0]][0]
1275
+ new_name = np.delete(sections, np.where(test_digit)[0]) #np.where(test_digit)[0]
1276
+ new_name = '_'.join(list(new_name))
1277
+ new_name = new_name.replace('intensity', channel_name)
1278
+ new_name = new_name.replace('-','_')
1279
+ new_name = new_name.replace('_nanmean','_mean')
1280
+
1281
+ to_rename.update({intensity_cols[k]: new_name})
1282
+
1283
+ if 'centre' in intensity_cols[k]:
1269
1284
 
1270
- channel_name = channel_names[np.where(channel_indices==index)[0]][0]
1271
- new_name = np.delete(sections, np.where(test_digit)[0]) #np.where(test_digit)[0]
1285
+ measure = np.array(re.split('-|_', new_name))
1286
+
1287
+ if sections[-2] == "0":
1288
+ new_name = np.delete(measure, -1)
1272
1289
  new_name = '_'.join(list(new_name))
1273
- new_name = new_name.replace('intensity', channel_name)
1274
- new_name = new_name.replace('-','_')
1275
- new_name = new_name.replace('_nanmean','_mean')
1276
-
1277
- to_rename.update({intensity_columns[k]: new_name})
1278
-
1279
- if 'centre' in intensity_columns[k]:
1280
- # sections = np.array(re.split('-|_', intensity_columns[k]))
1281
- measure = np.array(re.split('-|_', new_name))
1282
- if sections[-2] == "0":
1283
- new_name = np.delete(measure, -1)
1284
- new_name = '_'.join(list(new_name))
1285
- if 'edge' in intensity_columns[k]:
1286
- new_name = new_name.replace('centre_of_mass_displacement', "edge_centre_of_mass_displacement_in_px")
1287
- else:
1288
- new_name = new_name.replace('centre_of_mass', "centre_of_mass_displacement_in_px")
1289
- to_rename.update({intensity_columns[k]: new_name.replace('-', '_')})
1290
- elif sections[-2] == "1":
1291
- new_name = np.delete(measure, -1)
1292
- new_name = '_'.join(list(new_name))
1293
- if 'edge' in intensity_columns[k]:
1294
- new_name = new_name.replace('centre_of_mass_displacement', "edge_centre_of_mass_orientation")
1295
- else:
1296
- new_name = new_name.replace('centre_of_mass', "centre_of_mass_orientation")
1297
- to_rename.update({intensity_columns[k]: new_name.replace('-', '_')})
1298
- elif sections[-2] == "2":
1299
- new_name = np.delete(measure, -1)
1300
- new_name = '_'.join(list(new_name))
1301
- if 'edge' in intensity_columns[k]:
1302
- new_name = new_name.replace('centre_of_mass_displacement', "edge_centre_of_mass_x")
1303
- else:
1304
- new_name = new_name.replace('centre_of_mass', "centre_of_mass_x")
1305
- to_rename.update({intensity_columns[k]: new_name.replace('-', '_')})
1306
- elif sections[-2] == "3":
1307
- new_name = np.delete(measure, -1)
1308
- new_name = '_'.join(list(new_name))
1309
- if 'edge' in intensity_columns[k]:
1310
- new_name = new_name.replace('centre_of_mass_displacement', "edge_centre_of_mass_y")
1311
- else:
1312
- new_name = new_name.replace('centre_of_mass', "centre_of_mass_y")
1313
- to_rename.update({intensity_columns[k]: new_name.replace('-', '_')})
1314
- if 'radial_gradient' in intensity_columns[k]:
1315
- # sections = np.array(re.split('-|_', intensity_columns[k]))
1316
- measure = np.array(re.split('-|_', new_name))
1317
- if sections[-2] == "0":
1318
- new_name = np.delete(measure, -1)
1319
- new_name = '_'.join(list(measure))
1320
- new_name = new_name.replace('radial_gradient', "radial_gradient")
1321
- to_rename.update({intensity_columns[k]: new_name.replace('-', '_')})
1322
- elif sections[-2] == "1":
1323
- new_name = np.delete(measure, -1)
1324
- new_name = '_'.join(list(measure))
1325
- new_name = new_name.replace('radial_gradient', "radial_intercept")
1326
- to_rename.update({intensity_columns[k]: new_name.replace('-', '_')})
1327
- else:
1328
- to_rename = {}
1329
- for k in range(len(intensity_columns)):
1330
- sections = np.array(re.split('_|-', intensity_columns[k]))
1331
- channel_name = channel_names[0]
1332
- test_digit = np.array([s.isdigit() for s in sections])
1333
- new_name = np.delete(sections, np.where(test_digit)[0])
1290
+ if 'edge' in intensity_cols[k]:
1291
+ new_name = new_name.replace('center_of_mass_displacement', "edge_center_of_mass_displacement_in_px")
1292
+ else:
1293
+ new_name = new_name.replace('center_of_mass', "center_of_mass_displacement_in_px")
1294
+ to_rename.update({intensity_cols[k]: new_name.replace('-', '_')})
1295
+
1296
+ elif sections[-2] == "1":
1297
+ new_name = np.delete(measure, -1)
1298
+ new_name = '_'.join(list(new_name))
1299
+ if 'edge' in intensity_cols[k]:
1300
+ new_name = new_name.replace('center_of_mass_displacement', "edge_center_of_mass_orientation")
1301
+ else:
1302
+ new_name = new_name.replace('center_of_mass', "center_of_mass_orientation")
1303
+ to_rename.update({intensity_cols[k]: new_name.replace('-', '_')})
1304
+
1305
+ elif sections[-2] == "2":
1306
+ new_name = np.delete(measure, -1)
1307
+ new_name = '_'.join(list(new_name))
1308
+ if 'edge' in intensity_cols[k]:
1309
+ new_name = new_name.replace('center_of_mass_displacement', "edge_center_of_mass_x")
1310
+ else:
1311
+ new_name = new_name.replace('center_of_mass', "center_of_mass_x")
1312
+ to_rename.update({intensity_cols[k]: new_name.replace('-', '_')})
1313
+
1314
+ elif sections[-2] == "3":
1315
+ new_name = np.delete(measure, -1)
1334
1316
  new_name = '_'.join(list(new_name))
1335
- new_name = new_name.replace('intensity', channel_name)
1336
- to_rename.update({intensity_columns[k]: new_name.replace('-','_')})
1337
- if 'centre' in intensity_columns[k]:
1338
- measure = np.array(re.split('-|_', new_name))
1339
- if sections[-2] == "0":
1340
- new_name = np.delete(measure, -1)
1341
- new_name = '_'.join(list(new_name))
1342
- if 'edge' in intensity_columns[k]:
1343
- new_name = new_name.replace('centre_of_mass_displacement', "edge_centre_of_mass_displacement_in_px")
1344
- else:
1345
- new_name = new_name.replace('centre_of_mass', "centre_of_mass_displacement_in_px")
1346
- to_rename.update({intensity_columns[k]: new_name.replace('-', '_')})
1347
- if sections[-2] == "1":
1348
- new_name = np.delete(measure, -1)
1349
- new_name = '_'.join(list(new_name))
1350
- if 'edge' in intensity_columns[k]:
1351
- new_name = new_name.replace('centre_of_mass_displacement', "edge_centre_of_mass_orientation")
1352
- else:
1353
- new_name = new_name.replace('centre_of_mass', "centre_of_mass_orientation")
1354
- to_rename.update({intensity_columns[k]: new_name.replace('-', '_')})
1355
- if 'radial_gradient' in intensity_columns[k]:
1356
- # sections = np.array(re.split('-|_', intensity_columns[k]))
1357
- measure = np.array(re.split('-|_', new_name))
1358
- if sections[-2] == "0":
1359
- #new_name = np.delete(measure, -1)
1360
- new_name = '_'.join(list(measure))
1361
- new_name = new_name.replace('radial_gradient', "radial_gradient")
1362
- to_rename.update({intensity_columns[k]: new_name.replace('-', '_')})
1363
- elif sections[-2] == "1":
1364
- #new_name = np.delete(measure, -1)
1365
- new_name = '_'.join(list(measure))
1366
- new_name = new_name.replace('radial_gradient', "radial_intercept")
1367
- to_rename.update({intensity_columns[k]: new_name.replace('-', '_')})
1368
-
1369
- df = df.rename(columns=to_rename)
1317
+ if 'edge' in intensity_cols[k]:
1318
+ new_name = new_name.replace('center_of_mass_displacement', "edge_center_of_mass_y")
1319
+ else:
1320
+ new_name = new_name.replace('center_of_mass', "center_of_mass_y")
1321
+ to_rename.update({intensity_cols[k]: new_name.replace('-', '_')})
1322
+
1323
+ if 'radial_gradient' in intensity_cols[k]:
1324
+ # sections = np.array(re.split('-|_', intensity_columns[k]))
1325
+ measure = np.array(re.split('-|_', new_name))
1326
+
1327
+ if sections[-2] == "0":
1328
+ new_name = np.delete(measure, -1)
1329
+ new_name = '_'.join(list(measure))
1330
+ new_name = new_name.replace('radial_gradient', "radial_gradient")
1331
+ to_rename.update({intensity_cols[k]: new_name.replace('-', '_')})
1332
+
1333
+ elif sections[-2] == "1":
1334
+ new_name = np.delete(measure, -1)
1335
+ new_name = '_'.join(list(measure))
1336
+ new_name = new_name.replace('radial_gradient', "radial_intercept")
1337
+ to_rename.update({intensity_cols[k]: new_name.replace('-', '_')})
1338
+
1339
+ elif sections[-2] == "2":
1340
+ new_name = np.delete(measure, -1)
1341
+ new_name = '_'.join(list(measure))
1342
+ new_name = new_name.replace('radial_gradient', "radial_gradient_r2_score")
1343
+ to_rename.update({intensity_cols[k]: new_name.replace('-', '_')})
1370
1344
 
1345
+ df = df.rename(columns=to_rename)
1346
+
1371
1347
  return df
1372
1348
 
1373
1349
 
@@ -2064,7 +2040,7 @@ def _get_img_num_per_channel(channels_indices, len_movie, nbr_channels):
2064
2040
  >>> img_num_per_channel = _get_img_num_per_channel(channels_indices, len_movie, nbr_channels)
2065
2041
  >>> print(img_num_per_channel)
2066
2042
  # array([[ 1, 4, 7, 10, 13, 16, 19, 22, 25, 28],
2067
- # [ 2, 5, 8, 11, 14, 17, 20, 23, 26, 29]])
2043
+ # [ 2, 5, 8, 11, 14, 17, 20, 23, 26, 29]])
2068
2044
 
2069
2045
  """
2070
2046
 
@@ -2152,9 +2128,9 @@ def _extract_channels_from_config(config):
2152
2128
  >>> channels, indices = _extract_channels_from_config(config)
2153
2129
  >>> print(channels)
2154
2130
  # array(['brightfield_channel', 'adhesion_channel', 'fitc_channel',
2155
- # 'cy5_channel'], dtype='<U19')
2156
- >>> print(indices)
2157
- # array([0, 1, 2, 3])
2131
+ # 'cy5_channel'], dtype='<U19')
2132
+ >>> print(indices)
2133
+ # array([0, 1, 2, 3])
2158
2134
  """
2159
2135
 
2160
2136
  channel_names = []
@@ -2203,9 +2179,9 @@ def extract_experiment_channels(experiment):
2203
2179
  >>> channels, indices = extract_experiment_channels(experiment)
2204
2180
  >>> print(channels)
2205
2181
  # array(['brightfield_channel', 'adhesion_channel', 'fitc_channel',
2206
- # 'cy5_channel'], dtype='<U19')
2207
- >>> print(indices)
2208
- # array([0, 1, 2, 3])
2182
+ # 'cy5_channel'], dtype='<U19')
2183
+ >>> print(indices)
2184
+ # array([0, 1, 2, 3])
2209
2185
  """
2210
2186
 
2211
2187
  config = get_config(experiment)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: celldetective
3
- Version: 1.3.9.post2
3
+ Version: 1.3.9.post4
4
4
  Summary: description
5
5
  Home-page: http://github.com/remyeltorro/celldetective
6
6
  Author: Rémy Torro
@@ -1,10 +1,10 @@
1
1
  celldetective/__init__.py,sha256=bi3SGTMo6s2qQBsJAaKy-a4xaGcTQVW8zsqaiX5XKeY,139
2
2
  celldetective/__main__.py,sha256=bxTlSvbKhqn3LW_azd2baDCnDsgb37PAP9DfuAJ1_5M,1844
3
- celldetective/_version.py,sha256=-L_OTdOS0yLx8w7SqORxWfMGshbo1ITN75NdQT0lis0,28
3
+ celldetective/_version.py,sha256=-wBVuq0KoOI1lWnD4DhV-4xOLeDCprVOid1FqpG037I,28
4
4
  celldetective/events.py,sha256=UkjY_-THo6WviWWCLnDbma7jWOd_O9a60C4IOX2htG8,8254
5
- celldetective/extra_properties.py,sha256=PUs-lltSj_jSko_Gd-w483OxZW6oR3BAHQrw51DUxMg,8081
5
+ celldetective/extra_properties.py,sha256=LRJ1SRp9dvH_tpSEYv25wJFvaSg-95jFpzKLZwWvA3I,8689
6
6
  celldetective/filters.py,sha256=6pl2IGPK2FH8KPWbjzQEbT4C-ruqE1fQ8NQNN7Euvy8,4433
7
- celldetective/io.py,sha256=HEy9KbidrPVbzzbC1kJcXR0TsvIxNgRiDk31ecdjxpE,121954
7
+ celldetective/io.py,sha256=KDb1N7ccUAUXKE2NHo9TIC7A5u2A9wYieGteoa0ymN0,121754
8
8
  celldetective/measure.py,sha256=h1F08Vf7sy-20syMFZTUl1lHzE4h6cQvswJpwD9fcfE,58475
9
9
  celldetective/neighborhood.py,sha256=s-zVsfGnPlqs6HlDJCXRh21lLiPKbA_S1JC6uZvfG_0,56712
10
10
  celldetective/preprocessing.py,sha256=Wlt_PJua97CpMuWe_M65znUmz_yjYPqWIcs2ZK_RLgk,44109
@@ -12,7 +12,7 @@ celldetective/relative_measurements.py,sha256=-GWig0lC5UWAcJSPlo9Sp45khGj80fxuQf
12
12
  celldetective/segmentation.py,sha256=WApzoU1s3Ntvp0eIw_pRZXNwCA8LDKC9YoyR52tioz4,30943
13
13
  celldetective/signals.py,sha256=nMyyGUpla8D2sUYKY1zjbWsAueVPI_gUalY0KXfWteI,111595
14
14
  celldetective/tracking.py,sha256=VBJLd-1EeJarOVPBNEomhVBh9UYAMdSnH0tmUiUoTrY,40242
15
- celldetective/utils.py,sha256=RzC5yzuspnqF0_FG20mFTlrvPR2l5tpW0fyL32JccqY,106342
15
+ celldetective/utils.py,sha256=u9mvb4ajP4eE_usnkz9fBxkVOLrd2HfuPPE9FgAhTbc,104404
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=TPKWYczhPHvPKWg654sXnE9xCEx6U-oWX0_OJgLTWbU,15044
@@ -20,7 +20,7 @@ celldetective/gui/__init__.py,sha256=2_r2xfOj4_2xj0yBkCTIfzlF94AHKm-j6Pvpd7DddQc
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
22
  celldetective/gui/btrack_options.py,sha256=F2wrhuaNSaBr6vNApI22XSjdI5Cl3q138qCYBk-FDu4,44684
23
- celldetective/gui/classifier_widget.py,sha256=nHWmaWXse2CxxRFmR4mA0JRADr5i0MsWldaqJQIQ-i8,19992
23
+ celldetective/gui/classifier_widget.py,sha256=73h13QFtvYEy_jLl2DfSy9P3ERIOjWJAPn5mllYMPGc,20224
24
24
  celldetective/gui/configure_new_exp.py,sha256=N4SdL-4Xo0XbTAkCtt1ywr74HmHc5eaPlHGv1XgxAX0,20772
25
25
  celldetective/gui/control_panel.py,sha256=jFpedm03x6_jKabeadsNiigKnlh7sXCkulwe4gMCJaM,22042
26
26
  celldetective/gui/generic_signal_plot.py,sha256=Gv4KhA5vhbgVSj5jteE42T0aNCoQZtmIAUkEsMi6JNA,36309
@@ -31,7 +31,7 @@ celldetective/gui/measurement_options.py,sha256=sxtQPKSixVbrFcBC1XLLC4-h7ZHlgTLc
31
31
  celldetective/gui/neighborhood_options.py,sha256=FBNDvlzMPKp8s0Grxds90pCPHG1s27XrpMN0HV2gf0I,19839
32
32
  celldetective/gui/plot_measurements.py,sha256=n0pDUcYcsKlSMaUaBSVplGziuWp_7jKaeXdREs-MqyI,50848
33
33
  celldetective/gui/plot_signals_ui.py,sha256=7jCu-wLk_NDL4ThLZwhltODngre8iqPMUcEhJNNllo8,18189
34
- celldetective/gui/process_block.py,sha256=dH0zHIEouL8ApAD4uN7IR9dSl8X8QqE-hXL6U7HZHaM,71212
34
+ celldetective/gui/process_block.py,sha256=rFmtrnYBohjNRqSTjxC86yDNnzcXE7w9eo9Vm0heh6A,71215
35
35
  celldetective/gui/retrain_segmentation_model_options.py,sha256=7iawDN4kwq56Z-dX9kQe9tLW8B3YMrIW_D85LMAAYwk,23906
36
36
  celldetective/gui/retrain_signal_model_options.py,sha256=GCa0WKKsgmH2CFDHAKxPGbHtCE19p1_bbcWNasyZw5o,22482
37
37
  celldetective/gui/seg_model_loader.py,sha256=b1BiHuAf_ZqroE4jSEVCo7ASQv-xyWMPWU799alpbNM,19727
@@ -41,7 +41,7 @@ celldetective/gui/signal_annotator_options.py,sha256=Tq20tybpelHFUqFCSemqH9es2Fq
41
41
  celldetective/gui/styles.py,sha256=SZy_ACkA6QB_4ANyY1V0m1QF66C0SVGssOrwW1Qt1Aw,5076
42
42
  celldetective/gui/survival_ui.py,sha256=Q-530cAK-SsKPr8sWFTbhGekB2CFLWd0SNjtV1Wr0oo,14202
43
43
  celldetective/gui/tableUI.py,sha256=Yz_pHk1ERXRb0QsBPrvLEwAGpvVlawgn1b6uzz5wL_0,58022
44
- celldetective/gui/thresholds_gui.py,sha256=O7NkeaPV1nnQdTbduXd3lMttWPBzKcJ-9jI5OMr8H-0,48808
44
+ celldetective/gui/thresholds_gui.py,sha256=nxKYcEAGVdnQK0RM8pOu9MtYuBIYEvXiQCygzRjhv08,48810
45
45
  celldetective/gui/viewers.py,sha256=HDLB6j1FJwgKR6dQwzeHmcDvDMbDIYwD2svd-VZhJFE,47806
46
46
  celldetective/gui/workers.py,sha256=P4qUMXuCtGcggGmJr3VitAPSfRG30wkJ1B0pfcdGbKg,4225
47
47
  celldetective/gui/help/DL-segmentation-strategy.json,sha256=PZD9xXjrwbX3TiudHJPuvcyZD28o4k-fVgeTd7dBKzI,1583
@@ -56,7 +56,7 @@ celldetective/gui/help/propagate-classification.json,sha256=F7Ir1mtgRVTXWLN7n3ny
56
56
  celldetective/gui/help/track-postprocessing.json,sha256=VaGd8EEkA33OL-EI3NXWZ8yHeWWyUeImDF5yAjsVYGA,3990
57
57
  celldetective/gui/help/tracking.json,sha256=yIAoOToqCSQ_XF4gwEZCcyXcvQ3mROju263ZPDvlUyY,776
58
58
  celldetective/gui/processes/downloader.py,sha256=SuMTuM82QOZBqLfj36I14fhZ2k3NmLp0PBcGUHxnpXI,3287
59
- celldetective/gui/processes/measure_cells.py,sha256=gnUJzvmLt7hMpGVoqlBayv8ibdu9tvKaFbON_BE7NH0,12966
59
+ celldetective/gui/processes/measure_cells.py,sha256=7JPNkUCZ-w8v7yW-jwghH70Auk-IMOjlsnZlfr1Qjp0,12966
60
60
  celldetective/gui/processes/segment_cells.py,sha256=49Bh3nejkrxlLNhlP3Y_6-flkBOhkqFMQmrc2qDj7Dk,11320
61
61
  celldetective/gui/processes/track_cells.py,sha256=y8ohHAMcGtAjrJOP1WqvDfy_K85LbmdXoN7CA7BYpaY,9942
62
62
  celldetective/gui/processes/train_segmentation_model.py,sha256=bvcPG19hBjhNY9hd6Ch5_wk2FOJYQg97Azoz4RKeP-0,10776
@@ -99,14 +99,14 @@ celldetective/models/tracking_configs/no_z_motion.json,sha256=b4RWOJ0w6Y2e0vJYwK
99
99
  celldetective/models/tracking_configs/ricm.json,sha256=L-vmwCR1f89U-qnH2Ms0cBfPFR_dxIWoe2ccH8V-QBA,2727
100
100
  celldetective/models/tracking_configs/ricm2.json,sha256=DDjJ6ScYcDWvlsy7ujPID8v8H28vcNcMuZmNR8XmGxo,2718
101
101
  celldetective/regionprops/__init__.py,sha256=ohe9vC7j4lnpKnGXidVo1PVfoQfC8TqCuHTNo8rXmdg,44
102
- celldetective/regionprops/_regionprops.py,sha256=K1yHZDdLe81N9w73XMmRVLVsaMXJ3IE5VLP8ui6QsL4,9855
102
+ celldetective/regionprops/_regionprops.py,sha256=a68bAytxgy-WFUzrjWg-xViSE27ehN9PdKfyO-dxKxM,10275
103
103
  celldetective/regionprops/props.json,sha256=sCwACmbh0n-JAw9eve9yV85REukoMBJLsRjxCwTRMm8,2424
104
104
  celldetective/scripts/analyze_signals.py,sha256=YE05wZujl2hQFWkvqATBcCx-cAd_V3RxnvKoh0SB7To,2194
105
- celldetective/scripts/measure_cells.py,sha256=GvuHrSb3S-JnUjBaACx84BhUd_vUrwEHiSgDV9BoXXE,11766
105
+ celldetective/scripts/measure_cells.py,sha256=edZ9xlUsLg1TI_yudp7bd04B_oqdHk9Ee4mSDe8G86w,11769
106
106
  celldetective/scripts/measure_relative.py,sha256=wI7ibgWCsh5NVfcYum9LK0khL7cwKyCxwHFaXG4oWjM,3698
107
107
  celldetective/scripts/segment_cells.py,sha256=AZfHqig0WBMkAh9ho7JHmjM9vMO-EiPVviTHJcDj5Mw,6954
108
- celldetective/scripts/segment_cells_thresholds.py,sha256=lsW5hsHenNPiyIwZuZHipeCN2Wer69VcLko5rS96GAU,5118
109
- celldetective/scripts/track_cells.py,sha256=_OPfn9BsbvdpAU4dg36SXmOTx_BkDkZL4N05X0_Tig4,8795
108
+ celldetective/scripts/segment_cells_thresholds.py,sha256=J_QW53ndopSeq-uelBa2oTUCC2wG_FFCahEnn7PYpUE,5121
109
+ celldetective/scripts/track_cells.py,sha256=3I83-rkaShSzBSvYH0OVzjcgHeIohCxumA5W-lHg5Rw,8798
110
110
  celldetective/scripts/train_segmentation_model.py,sha256=XExaGg8kkdirgN206J0mwiWtqeRE076-Ld2b89tReAI,9229
111
111
  celldetective/scripts/train_signal_model.py,sha256=D643wKVYg-LWHF2VU9FWKSuazXrpCpQK0YjGqoIimD0,3167
112
112
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -121,9 +121,9 @@ tests/test_segmentation.py,sha256=k1b_zIZdlytEdJcHjAUQEO3gTBAHtv5WvrwQN2xD4kc,34
121
121
  tests/test_signals.py,sha256=No4cah6KxplhDcKXnU8RrA7eDla4hWw6ccf7xGnBokU,3599
122
122
  tests/test_tracking.py,sha256=8hebWSqEIuttD1ABn-6dKCT7EXKRR7-4RwyFWi1WPFo,8800
123
123
  tests/test_utils.py,sha256=NKRCAC1d89aBK5cWjTb7-pInYow901RrT-uBlIdz4KI,3692
124
- celldetective-1.3.9.post2.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
125
- celldetective-1.3.9.post2.dist-info/METADATA,sha256=32q8-6ZVwiHP3ScLNJ4NKCuyZFQp-WjNdGE_Z6HuOHk,10753
126
- celldetective-1.3.9.post2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
127
- celldetective-1.3.9.post2.dist-info/entry_points.txt,sha256=2NU6_EOByvPxqBbCvjwxlVlvnQreqZ3BKRCVIKEv3dg,62
128
- celldetective-1.3.9.post2.dist-info/top_level.txt,sha256=6rsIKKfGMKgud7HPuATcpq6EhdXwcg_yknBVWn9x4C4,20
129
- celldetective-1.3.9.post2.dist-info/RECORD,,
124
+ celldetective-1.3.9.post4.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
125
+ celldetective-1.3.9.post4.dist-info/METADATA,sha256=_UdO696o0Et9eTWHRKOl6NSn8eC8puV1y1G25M8qCEU,10753
126
+ celldetective-1.3.9.post4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
127
+ celldetective-1.3.9.post4.dist-info/entry_points.txt,sha256=2NU6_EOByvPxqBbCvjwxlVlvnQreqZ3BKRCVIKEv3dg,62
128
+ celldetective-1.3.9.post4.dist-info/top_level.txt,sha256=6rsIKKfGMKgud7HPuATcpq6EhdXwcg_yknBVWn9x4C4,20
129
+ celldetective-1.3.9.post4.dist-info/RECORD,,