spacr 0.4.15__py3-none-any.whl → 0.4.60__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.
spacr/utils.py CHANGED
@@ -78,7 +78,7 @@ def filepaths_to_database(img_paths, settings, source_folder, crop_mode):
78
78
 
79
79
  parts = png_df['file_name'].apply(lambda x: pd.Series(_map_wells_png(x, timelapse=settings['timelapse'])))
80
80
 
81
- columns = ['plate', 'row_name', 'column_name', 'field']
81
+ columns = ['plateID', 'rowID', 'columnID', 'fieldID']
82
82
 
83
83
  if settings['timelapse']:
84
84
  columns = columns + ['time_id']
@@ -113,7 +113,7 @@ def activation_maps_to_database(img_paths, source_folder, settings):
113
113
  png_df = pd.DataFrame(img_paths, columns=['png_path'])
114
114
  png_df['file_name'] = png_df['png_path'].apply(lambda x: os.path.basename(x))
115
115
  parts = png_df['file_name'].apply(lambda x: pd.Series(_map_wells_png(x, timelapse=False)))
116
- columns = ['plate', 'row_name', 'column_name', 'field', 'prcfo', 'object']
116
+ columns = ['plateID', 'rowID', 'columnID', 'fieldID', 'prcfo', 'object']
117
117
  png_df[columns] = parts
118
118
 
119
119
  dataset_name = os.path.splitext(os.path.basename(settings['dataset']))[0]
@@ -136,7 +136,7 @@ def activation_correlations_to_database(df, img_paths, source_folder, settings):
136
136
  png_df = pd.DataFrame(img_paths, columns=['png_path'])
137
137
  png_df['file_name'] = png_df['png_path'].apply(lambda x: os.path.basename(x))
138
138
  parts = png_df['file_name'].apply(lambda x: pd.Series(_map_wells_png(x, timelapse=False)))
139
- columns = ['plate', 'row_name', 'column_name', 'field', 'prcfo', 'object']
139
+ columns = ['plateID', 'rowID', 'columnID', 'fieldID', 'prcfo', 'object']
140
140
  png_df[columns] = parts
141
141
 
142
142
  # Align both DataFrames by file_name
@@ -319,18 +319,26 @@ def load_settings(csv_file_path, show=False, setting_key='setting_key', setting_
319
319
 
320
320
  return result_dict
321
321
 
322
-
323
322
  def save_settings(settings, name='settings', show=False):
324
323
 
325
- settings_df = pd.DataFrame(list(settings.items()), columns=['Key', 'Value'])
326
- if show:
327
- display(settings_df)
324
+ settings_2 = settings.copy()
328
325
 
329
- if isinstance(settings['src'], list):
330
- src = settings['src'][0]
326
+ if isinstance(settings_2['src'], list):
327
+ src = settings_2['src'][0]
331
328
  name = f"{name}_list"
332
329
  else:
333
- src = settings['src']
330
+ src = settings_2['src']
331
+
332
+ if 'test_mode' in settings_2.keys():
333
+ settings_2['test_mode'] = False
334
+
335
+ if 'plot' in settings_2.keys():
336
+ settings_2['plot'] = False
337
+
338
+ settings_df = pd.DataFrame(list(settings_2.items()), columns=['Key', 'Value'])
339
+
340
+ if show:
341
+ display(settings_df)
334
342
 
335
343
  settings_csv = os.path.join(src,'settings',f'{name}.csv')
336
344
  os.makedirs(os.path.join(src,'settings'), exist_ok=True)
@@ -549,7 +557,7 @@ def _get_cellpose_batch_size():
549
557
  def _extract_filename_metadata(filenames, src, regular_expression, metadata_type='cellvoyager', pick_slice=False, skip_mode='01'):
550
558
 
551
559
  images_by_key = defaultdict(list)
552
-
560
+
553
561
  for filename in filenames:
554
562
  match = regular_expression.match(filename)
555
563
  if match:
@@ -592,7 +600,7 @@ def _extract_filename_metadata(filenames, src, regular_expression, metadata_type
592
600
  except IndexError:
593
601
  print(f"Could not extract information from filename {filename} using provided regex")
594
602
  else:
595
- print(f"Filename {filename} did not match provided regex")
603
+ print(f"Filename {filename} did not match provided regex: {regular_expression}")
596
604
  continue
597
605
 
598
606
  return images_by_key
@@ -634,11 +642,11 @@ def _update_database_with_merged_info(db_path, df, table='png_list', columns=['p
634
642
  if 'prcfo' not in df.columns:
635
643
  print(f'generating prcfo columns')
636
644
  try:
637
- df['prcfo'] = df['plate'].astype(str) + '_' + df['row_name'].astype(str) + '_' + df['column_name'].astype(str) + '_' + df['field'].astype(str) + '_o' + df['object_label'].astype(int).astype(str)
645
+ df['prcfo'] = df['plateID'].astype(str) + '_' + df['rowID'].astype(str) + '_' + df['columnID'].astype(str) + '_' + df['fieldID'].astype(str) + '_o' + df['object_label'].astype(int).astype(str)
638
646
  except Exception as e:
639
647
  print('Merging on cell failed, trying with cell_id')
640
648
  try:
641
- df['prcfo'] = df['plate'].astype(str) + '_' + df['row_name'].astype(str) + '_' + df['column_name'].astype(str) + '_' + df['field'].astype(str) + '_o' + df['cell_id'].astype(int).astype(str)
649
+ df['prcfo'] = df['plateID'].astype(str) + '_' + df['rowID'].astype(str) + '_' + df['columnID'].astype(str) + '_' + df['fieldID'].astype(str) + '_o' + df['cell_id'].astype(int).astype(str)
642
650
  except Exception as e:
643
651
  print(e)
644
652
 
@@ -730,7 +738,7 @@ def _map_values(row, values, locs):
730
738
  if locs:
731
739
  value_dict = {loc: value for value, loc_list in zip(values, locs) for loc in loc_list}
732
740
  # Determine if we're dealing with row or column based on first location identifier
733
- type_ = 'row_name' if locs[0][0][0] == 'r' else 'column_name'
741
+ type_ = 'rowID' if locs[0][0][0] == 'r' else 'columnID'
734
742
  return value_dict.get(row[type_], None)
735
743
  return values[0] if values else None
736
744
 
@@ -915,21 +923,21 @@ def _merge_and_save_to_database(morph_df, intensity_df, table_type, source_folde
915
923
  merged_df['file_name'] = file_name
916
924
  merged_df['path_name'] = os.path.join(source_folder, file_name + '.npy')
917
925
  if timelapse:
918
- merged_df[['plate', 'row_name', 'column_name', 'field', 'timeid', 'prcf']] = merged_df['file_name'].apply(lambda x: pd.Series(_map_wells(x, timelapse)))
926
+ merged_df[['plateID', 'rowID', 'columnID', 'fieldID', 'timeid', 'prcf']] = merged_df['file_name'].apply(lambda x: pd.Series(_map_wells(x, timelapse)))
919
927
  else:
920
- merged_df[['plate', 'row_name', 'column_name', 'field', 'prcf']] = merged_df['file_name'].apply(lambda x: pd.Series(_map_wells(x, timelapse)))
928
+ merged_df[['plateID', 'rowID', 'columnID', 'fieldID', 'prcf']] = merged_df['file_name'].apply(lambda x: pd.Series(_map_wells(x, timelapse)))
921
929
  cols = merged_df.columns.tolist() # get the list of all columns
922
930
  if table_type == 'cell' or table_type == 'cytoplasm':
923
- column_list = ['object_label', 'plate', 'row_name', 'column_name', 'field', 'prcf', 'file_name', 'path_name']
931
+ column_list = ['object_label', 'plateID', 'rowID', 'columnID', 'fieldID', 'prcf', 'file_name', 'path_name']
924
932
  elif table_type == 'nucleus' or table_type == 'pathogen':
925
- column_list = ['object_label', 'cell_id', 'plate', 'row_name', 'column_name', 'field', 'prcf', 'file_name', 'path_name']
933
+ column_list = ['object_label', 'cell_id', 'plateID', 'rowID', 'columnID', 'fieldID', 'prcf', 'file_name', 'path_name']
926
934
  else:
927
935
  raise ValueError(f"Invalid table_type: {table_type}")
928
936
  # Check if all columns in column_list are in cols
929
937
  missing_columns = [col for col in column_list if col not in cols]
930
938
  if len(missing_columns) == 1 and missing_columns[0] == 'cell_id':
931
939
  missing_columns = False
932
- column_list = ['object_label', 'plate', 'row_name', 'column_name', 'field', 'prcf', 'file_name', 'path_name']
940
+ column_list = ['object_label', 'plateID', 'rowID', 'columnID', 'fieldID', 'prcf', 'file_name', 'path_name']
933
941
  if missing_columns:
934
942
  raise ValueError(f"Columns missing in DataFrame: {missing_columns}")
935
943
  for i, col in enumerate(column_list):
@@ -1143,43 +1151,6 @@ def _masks_to_masks_stack(masks):
1143
1151
  for idx, mask in enumerate(masks):
1144
1152
  mask_stack.append(mask)
1145
1153
  return mask_stack
1146
-
1147
- def _get_diam_v1(mag, obj):
1148
-
1149
- if mag == 20:
1150
- if obj == 'cell':
1151
- diamiter = 120
1152
- elif obj == 'nucleus':
1153
- diamiter = 60
1154
- elif obj == 'pathogen':
1155
- diamiter = 20
1156
- else:
1157
- raise ValueError("Invalid magnification: Use 20, 40 or 60")
1158
-
1159
- elif mag == 40:
1160
- if obj == 'cell':
1161
- diamiter = 160
1162
- elif obj == 'nucleus':
1163
- diamiter = 80
1164
- elif obj == 'pathogen':
1165
- diamiter = 40
1166
- else:
1167
- raise ValueError("Invalid magnification: Use 20, 40 or 60")
1168
-
1169
- elif mag == 60:
1170
- if obj == 'cell':
1171
- diamiter = 200
1172
- if obj == 'nucleus':
1173
- diamiter = 90
1174
- if obj == 'pathogen':
1175
- diamiter = 60
1176
- else:
1177
- raise ValueError("Invalid magnification: Use 20, 40 or 60")
1178
-
1179
- else:
1180
- raise ValueError("Invalid magnification: Use 20, 40 or 60")
1181
-
1182
- return diamiter
1183
1154
 
1184
1155
  def _get_diam(mag, obj):
1185
1156
 
@@ -1339,11 +1310,11 @@ def annotate_conditions(df, cells=None, cell_loc=None, pathogens=None, pathogen_
1339
1310
  """
1340
1311
 
1341
1312
  def _get_type(val):
1342
- """Determine if a value maps to 'row_name' or 'column_name'."""
1313
+ """Determine if a value maps to 'rowID' or 'columnID'."""
1343
1314
  if isinstance(val, str) and val.startswith('c'):
1344
- return 'column_name'
1315
+ return 'columnID'
1345
1316
  elif isinstance(val, str) and val.startswith('r'):
1346
- return 'row_name'
1317
+ return 'rowID'
1347
1318
  return None
1348
1319
 
1349
1320
  def _map_or_default(column_name, values, loc, df):
@@ -1411,7 +1382,7 @@ def _split_data(df, group_by, object_type):
1411
1382
  # Ensure 'prcf' column exists by concatenating specific columns
1412
1383
  if 'prcf' not in df.columns:
1413
1384
  try:
1414
- df['prcf'] = df['plate'].astype(str) + '_' + df['row_name'].astype(str) + '_' + df['column_name'].astype(str) + '_' + df['field'].astype(str)
1385
+ df['prcf'] = df['plateID'].astype(str) + '_' + df['rowID'].astype(str) + '_' + df['columnID'].astype(str) + '_' + df['fieldID'].astype(str)
1415
1386
  except Exception as e:
1416
1387
  print(e)
1417
1388
 
@@ -1508,7 +1479,7 @@ def _group_by_well(df):
1508
1479
  non_numeric_cols = df.select_dtypes(include=['object']).columns
1509
1480
 
1510
1481
  # Apply mean function to numeric columns and first to non-numeric
1511
- df_grouped = df.groupby(['plate', 'row_name', 'column_name']).agg({**{col: np.mean for col in numeric_cols}, **{col: 'first' for col in non_numeric_cols}})
1482
+ df_grouped = df.groupby(['plateID', 'rowID', 'columnID']).agg({**{col: np.mean for col in numeric_cols}, **{col: 'first' for col in non_numeric_cols}})
1512
1483
  return df_grouped
1513
1484
 
1514
1485
  ###################################################
@@ -2187,11 +2158,11 @@ def augment_classes(dst, nc, pc, generate=True,move=True):
2187
2158
  def annotate_predictions(csv_loc):
2188
2159
  df = pd.read_csv(csv_loc)
2189
2160
  df['filename'] = df['path'].apply(lambda x: x.split('/')[-1])
2190
- df[['plate', 'well', 'field', 'object']] = df['filename'].str.split('_', expand=True)
2161
+ df[['plateID', 'well', 'fieldID', 'object']] = df['filename'].str.split('_', expand=True)
2191
2162
  df['object'] = df['object'].str.replace('.png', '')
2192
2163
 
2193
2164
  def assign_condition(row):
2194
- plate = int(row['plate'])
2165
+ plate = int(row['plateID'])
2195
2166
  col = int(row['well'][1:])
2196
2167
 
2197
2168
  if col > 3:
@@ -2342,7 +2313,7 @@ def check_multicollinearity(x):
2342
2313
 
2343
2314
  def lasso_reg(merged_df, alpha_value=0.01, reg_type='lasso'):
2344
2315
  # Separate predictors and response
2345
- X = merged_df[['gene', 'grna', 'plate', 'row_name', 'column']]
2316
+ X = merged_df[['gene', 'grna', 'plateID', 'rowID', 'columnID']]
2346
2317
  y = merged_df['pred']
2347
2318
 
2348
2319
  # One-hot encode the categorical predictors
@@ -3120,12 +3091,8 @@ def _get_regex(metadata_type, img_format, custom_regex=None):
3120
3091
  regex = f'(?P<plateID>.*)_(?P<wellID>.*)_T(?P<timeID>.*)F(?P<fieldID>.*)L(?P<laserID>..)A(?P<AID>..)Z(?P<sliceID>.*)C(?P<chanID>.*){img_format}'
3121
3092
  elif metadata_type == 'cq1':
3122
3093
  regex = f'W(?P<wellID>.*)F(?P<fieldID>.*)T(?P<timeID>.*)Z(?P<sliceID>.*)C(?P<chanID>.*){img_format}'
3123
- elif metadata_type == 'nikon':
3124
- regex = f'(?P<plateID>.*)_(?P<wellID>.*)_T(?P<timeID>.*)F(?P<fieldID>.*)L(?P<laserID>..)A(?P<AID>..)Z(?P<sliceID>.*)C(?P<chanID>.*){img_format}'
3125
- elif metadata_type == 'zeis':
3126
- regex = f'(?P<plateID>.*)_(?P<wellID>.*)_T(?P<timeID>.*)F(?P<fieldID>.*)L(?P<laserID>..)A(?P<AID>..)Z(?P<sliceID>.*)C(?P<chanID>.*){img_format}'
3127
- elif metadata_type == 'leica':
3128
- regex = f'(?P<plateID>.*)_(?P<wellID>.*)_T(?P<timeID>.*)F(?P<fieldID>.*)L(?P<laserID>..)A(?P<AID>..)Z(?P<sliceID>.*)C(?P<chanID>.*){img_format}'
3094
+ elif metadata_type == 'auto':
3095
+ regex = f'(?P<plateID>.*)_(?P<wellID>.*)_T(?P<timeID>.*)F(?P<fieldID>.*)L(?P<laserID>.*)C(?P<chanID>.*).tif'
3129
3096
  elif metadata_type == 'custom':
3130
3097
  regex = f'({custom_regex}){img_format}'
3131
3098
 
@@ -3143,7 +3110,7 @@ def _run_test_mode(src, regex, timelapse=False, test_images=10, random_test=True
3143
3110
 
3144
3111
  if os.path.exists(os.path.join(src, 'orig')):
3145
3112
  src = os.path.join(src, 'orig')
3146
-
3113
+
3147
3114
  all_filenames = [filename for filename in os.listdir(src) if regular_expression.match(filename)]
3148
3115
  print(f'Found {len(all_filenames)} files')
3149
3116
  images_by_set = defaultdict(list)
@@ -3185,7 +3152,6 @@ def _choose_model(model_name, device, object_type='cell', restore_type=None, obj
3185
3152
  model_path = os.path.join(current_dir, 'models', 'cp', 'toxo_pv_lumen.CP_model')
3186
3153
  print(model_path)
3187
3154
  model = cp_models.CellposeModel(gpu=torch.cuda.is_available(), model_type=None, pretrained_model=model_path, diam_mean=diameter, device=device)
3188
- #model = cp_models.Cellpose(gpu=torch.cuda.is_available(), model_type='cyto', device=device)
3189
3155
  print(f'Using Toxoplasma PV lumen model to generate pathogen masks')
3190
3156
  return model
3191
3157
 
@@ -4714,12 +4680,12 @@ def process_vision_results(df, threshold=0.5):
4714
4680
  # Split the 'path' column using _map_wells function
4715
4681
  mapped_values = df['path'].apply(lambda x: _map_wells(x))
4716
4682
 
4717
- df['plate'] = mapped_values.apply(lambda x: x[0])
4718
- df['row_name'] = mapped_values.apply(lambda x: x[1])
4719
- df['column'] = mapped_values.apply(lambda x: x[2])
4720
- df['field'] = mapped_values.apply(lambda x: x[3])
4683
+ df['plateID'] = mapped_values.apply(lambda x: x[0])
4684
+ df['rowID'] = mapped_values.apply(lambda x: x[1])
4685
+ df['columnID'] = mapped_values.apply(lambda x: x[2])
4686
+ df['fieldID'] = mapped_values.apply(lambda x: x[3])
4721
4687
  df['object'] = df['path'].str.split('_').str[3].str.split('.').str[0]
4722
- df['prc'] = df['plate'].astype(str) + '_' + df['row_name'].astype(str) + '_' + df['column'].astype(str)
4688
+ df['prc'] = df['plateID'].astype(str) + '_' + df['rowID'].astype(str) + '_' + df['columnID'].astype(str)
4723
4689
  df['cv_predictions'] = (df['pred'] >= threshold).astype(int)
4724
4690
 
4725
4691
  return df
@@ -5134,24 +5100,24 @@ def fill_holes_in_mask(mask):
5134
5100
 
5135
5101
  def correct_metadata_column_names(df):
5136
5102
  if 'plate_name' in df.columns:
5137
- df = df.rename(columns={'plate_name': 'plate'})
5103
+ df = df.rename(columns={'plate_name': 'plateID'})
5138
5104
  if 'column_name' in df.columns:
5139
- df = df.rename(columns={'column_name': 'column'})
5105
+ df = df.rename(columns={'column_name': 'columnID'})
5140
5106
  if 'col' in df.columns:
5141
- df = df.rename(columns={'col': 'column'})
5107
+ df = df.rename(columns={'col': 'columnID'})
5142
5108
  if 'row_name' in df.columns:
5143
- df = df.rename(columns={'row_name': 'row_name'})
5109
+ df = df.rename(columns={'row_name': 'rowID'})
5144
5110
  if 'grna_name' in df.columns:
5145
5111
  df = df.rename(columns={'grna_name': 'grna'})
5146
5112
  if 'plate_row' in df.columns:
5147
- df[['plate', 'row_name']] = df['plate_row'].str.split('_', expand=True)
5113
+ df[['plateID', 'rowID']] = df['plate_row'].str.split('_', expand=True)
5148
5114
  return df
5149
5115
 
5150
- def control_filelist(folder, mode='column', values=['01','02']):
5116
+ def control_filelist(folder, mode='columnID', values=['01','02']):
5151
5117
  files = os.listdir(folder)
5152
- if mode is 'column':
5118
+ if mode is 'columnID':
5153
5119
  filtered_files = [file for file in files if file.split('_')[1][1:] in values]
5154
- if mode is 'row_name':
5120
+ if mode is 'rowID':
5155
5121
  filtered_files = [file for file in files if file.split('_')[1][:1] in values]
5156
5122
  return filtered_files
5157
5123
 
@@ -5169,12 +5135,12 @@ def rename_columns_in_db(db_path):
5169
5135
  columns_info = cursor.fetchall()
5170
5136
  column_names = [col[1] for col in columns_info]
5171
5137
 
5172
- # Check if columns 'row' or 'col' exist
5138
+ # Check if columns 'rowID' or 'columnID' exist
5173
5139
  columns_to_rename = {}
5174
5140
  if 'row' in column_names:
5175
- columns_to_rename['row'] = 'row_name'
5141
+ columns_to_rename['row'] = 'rowID'
5176
5142
  if 'col' in column_names:
5177
- columns_to_rename['col'] = 'column_name'
5143
+ columns_to_rename['col'] = 'columnID'
5178
5144
 
5179
5145
  # Rename columns if necessary
5180
5146
  if columns_to_rename:
@@ -5418,3 +5384,110 @@ def normalize_src_path(src):
5418
5384
  return src # Return as a string if not a list
5419
5385
 
5420
5386
  raise ValueError(f"Invalid type for 'src': {type(src).__name__}, expected str or list")
5387
+
5388
+ def generate_image_path_map(root_folder, valid_extensions=("tif", "tiff", "png", "jpg", "jpeg", "bmp", "czi", "nd2", "lif")):
5389
+ """
5390
+ Recursively scans a folder and its subfolders for images, then creates a mapping of:
5391
+ {original_image_path: new_image_path}, where the new path includes all subfolder names.
5392
+
5393
+ Args:
5394
+ root_folder (str): The root directory to scan for images.
5395
+ valid_extensions (tuple): Tuple of valid image file extensions.
5396
+
5397
+ Returns:
5398
+ dict: A dictionary mapping original image paths to their new paths.
5399
+ """
5400
+ image_path_map = {}
5401
+
5402
+ for dirpath, _, filenames in os.walk(root_folder):
5403
+ for file in filenames:
5404
+ ext = file.lower().split('.')[-1]
5405
+ if ext in valid_extensions:
5406
+ # Get relative path of the image from root_folder
5407
+ relative_path = os.path.relpath(dirpath, root_folder)
5408
+
5409
+ # Construct new filename: Embed folder hierarchy into the name
5410
+ folder_parts = relative_path.split(os.sep) # Get all folder names
5411
+ folder_info = "_".join(folder_parts) if folder_parts else "" # Join with underscores
5412
+
5413
+ # Generate new filename
5414
+ new_filename = f"{folder_info}_{file}" if folder_info else file
5415
+
5416
+ # Store in dictionary (original path -> new path)
5417
+ original_path = os.path.join(dirpath, file)
5418
+ new_path = os.path.join(root_folder, new_filename)
5419
+ image_path_map[original_path] = new_path
5420
+
5421
+ return image_path_map
5422
+
5423
+ def copy_images_to_consolidated(image_path_map, root_folder):
5424
+ """
5425
+ Copies images from their original locations to a 'consolidated' folder,
5426
+ renaming them according to the generated dictionary.
5427
+
5428
+ Args:
5429
+ image_path_map (dict): Dictionary mapping {original_path: new_path}.
5430
+ root_folder (str): The root directory where the 'consolidated' folder will be created.
5431
+ """
5432
+
5433
+ consolidated_folder = os.path.join(root_folder, "consolidated")
5434
+ os.makedirs(consolidated_folder, exist_ok=True) # Ensure 'consolidated' folder exists
5435
+ files_processed = 0
5436
+ files_to_process = len(image_path_map)
5437
+ time_ls= []
5438
+
5439
+ for original_path, new_path in image_path_map.items():
5440
+
5441
+ start = time.time()
5442
+ new_filename = os.path.basename(new_path) # Extract only the new filename
5443
+ new_file_path = os.path.join(consolidated_folder, new_filename) # Place in 'consolidated' folder
5444
+
5445
+ shutil.copy2(original_path, new_file_path) # Copy file with metadata preserved
5446
+
5447
+ files_processed += 1
5448
+ stop = time.time()
5449
+ duration = (stop - start)
5450
+ time_ls.append(duration)
5451
+
5452
+ print_progress(files_processed, files_to_process, n_jobs=1, time_ls=time_ls, batch_size=None, operation_type=f'Consolidating images')
5453
+ #print(f"Copied: {original_path} -> {new_file_path}")
5454
+
5455
+ def correct_metadata(df):
5456
+
5457
+ #if 'object' in df.columns:
5458
+ # df['objectID'] = df['object']
5459
+
5460
+ if 'object_name' in df.columns:
5461
+ df['objectID'] = df['object_name']
5462
+
5463
+ if 'field_name' in df.columns:
5464
+ df['fieldID'] = df['field_name']
5465
+
5466
+ if 'plate' in df.columns:
5467
+ df['plateID'] = df['plate']
5468
+
5469
+ if 'plate_name' in df.columns:
5470
+ df['plateID'] = df['plate_name']
5471
+
5472
+ if 'row' in df.columns:
5473
+ df = df.rename(columns={'row': 'rowID'})
5474
+
5475
+ if 'row_name' in df.columns:
5476
+ df = df.rename(columns={'row_name': 'rowID'})
5477
+
5478
+ if 'col' in df.columns:
5479
+ df = df.rename(columns={'col': 'columnID'})
5480
+
5481
+ if 'column' in df.columns:
5482
+ df = df.rename(columns={'column': 'columnID'})
5483
+
5484
+ if 'column_name' in df.columns:
5485
+ df = df.rename(columns={'column_name': 'columnID'})
5486
+
5487
+ if 'field' in df.columns:
5488
+ df = df.rename(columns={'field': 'fieldID'})
5489
+
5490
+ if 'field_name' in df.columns:
5491
+ df = df.rename(columns={'field_name': 'fieldID'})
5492
+
5493
+ return df
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spacr
3
- Version: 0.4.15
3
+ Version: 0.4.60
4
4
  Summary: Spatial phenotype analysis of crisp screens (SpaCr)
5
5
  Home-page: https://github.com/EinarOlafsson/spacr
6
6
  Author: Einar Birnir Olafsson
@@ -41,6 +41,7 @@ Requires-Dist: pillow<11.0,>=10.2.0
41
41
  Requires-Dist: tifffile>=2023.4.12
42
42
  Requires-Dist: nd2reader<4.0,>=3.3.0
43
43
  Requires-Dist: czifile
44
+ Requires-Dist: readlif
44
45
  Requires-Dist: imageio<3.0,>=2.34.0
45
46
  Requires-Dist: pingouin<1.0,>=0.5.5
46
47
  Requires-Dist: umap-learn<1.0,>=0.5.6
@@ -9,28 +9,28 @@ spacr/app_sequencing.py,sha256=DjG26jy4cpddnV8WOOAIiExtOe9MleVMY4MFa5uTo5w,157
9
9
  spacr/app_umap.py,sha256=ZWAmf_OsIKbYvolYuWPMYhdlVe-n2CADoJulAizMiEo,153
10
10
  spacr/cellpose.py,sha256=RBHMs2vwXcfkj0xqAULpALyzJYXddSRycgZSzmwI7v0,14755
11
11
  spacr/chat_bot.py,sha256=n3Fhqg3qofVXHmh3H9sUcmfYy9MmgRnr48663MVdY9E,1244
12
- spacr/core.py,sha256=JfeXuLa-IR0Qn5SfNPj2NCyxRkVXE3MDy0ywPFLIFVY,49014
13
- spacr/deep_spacr.py,sha256=WN64EaQqF87JZg3Uan46t5Y28xsAGD2KMjr2ht6CyDs,54563
12
+ spacr/core.py,sha256=ghesCiRKxdHqnujztb9XiuhhZ-3gBs7aQIIzvqaf-iI,51409
13
+ spacr/deep_spacr.py,sha256=055tIo3WP3elGFiIuSZaLURgu2XyUDxAdbw5ezASEqM,54526
14
14
  spacr/gui.py,sha256=ARyn9Q_g8HoP-cXh1nzMLVFCKqthY4v2u9yORyaQqQE,8230
15
- spacr/gui_core.py,sha256=DFzYiauhLJF7koEeKSXZAoUeUHd74LRgdt6Xktqi254,46892
16
- spacr/gui_elements.py,sha256=HmITDncklKwtdFhxLhtYXOwndsRfgwWIPVi83VlXHB4,146419
17
- spacr/gui_utils.py,sha256=ZiRMYSBj1w5jIjoTBw9_kf9RbAZD9D0DYCNHUmxNrh8,41342
18
- spacr/io.py,sha256=BtmxZcA_fr8jFsuwisnG95E5DS14JGA9isqiI-iYdII,138923
15
+ spacr/gui_core.py,sha256=AYXZpdKMRezJfS7Xcfztdc2yco6lV21ovwkyKQGbIZg,56206
16
+ spacr/gui_elements.py,sha256=5a3BOpctBPklsT1NungqS72h1Bg1FArUndE0OfvWD8Y,152646
17
+ spacr/gui_utils.py,sha256=dWVPFwDj793Z3ERG4mMC0hI0MKkOrvXJpUYlcjpCBsU,41357
18
+ spacr/io.py,sha256=eZj5RCqje3xb_4BwPC0ASBqI-c7_6EeQYv8zrQf0tCc,159371
19
19
  spacr/logger.py,sha256=lJhTqt-_wfAunCPl93xE65Wr9Y1oIHJWaZMjunHUeIw,1538
20
20
  spacr/measure.py,sha256=Z3u4BU5RzcY82IZuboQ0OsxuXaPVwOlH65Rw6FrL5z4,55045
21
21
  spacr/mediar.py,sha256=FwLvbLQW5LQzPgvJZG8Lw7GniA2vbZx6Jv6vIKu7I5c,14743
22
- spacr/ml.py,sha256=MrIAtUUxMOibWVL1SjCUnYlizawCp3l3SeY4Y9yEsPw,97251
22
+ spacr/ml.py,sha256=XCRZeX7UkbMctQICIoskeWVx8CCmmCoHNauUOAkfFq0,91692
23
23
  spacr/openai.py,sha256=5vBZ3Jl2llYcW3oaTEXgdyCB2aJujMUIO5K038z7w_A,1246
24
- spacr/plot.py,sha256=Q5TbsR2NUWhA7z4HyF_2_FAEBFSNMU-G3UNDbRzW6mM,169485
25
- spacr/sequencing.py,sha256=ClUfwPPK6rNUbUuiEkzcwakzVyDKKUMv9ricrxT8qQY,25227
26
- spacr/settings.py,sha256=7NAW69yE9FNzsQlLE2lTnDFNL4042AI4c-y20ikPlxc,84793
24
+ spacr/plot.py,sha256=lmpIJozfxMyOyGAMno4j-C7NPjDYRMr29SDAnrV-bb4,170815
25
+ spacr/sequencing.py,sha256=EY12RdW5QRKpHDRQCw1QoAlxCq8FK2v6WoVa5uuDBXQ,26745
26
+ spacr/settings.py,sha256=j2H5OieJKwu-TITlfP5tAnUGUhBjng8ECy3jXm3JMb8,86599
27
27
  spacr/sim.py,sha256=1xKhXimNU3ukzIw-3l9cF3Znc_brW8h20yv8fSTzvss,71173
28
28
  spacr/sp_stats.py,sha256=mbhwsyIqt5upsSD346qGjdCw7CFBa0tIS7zHU9e0jNI,9536
29
29
  spacr/stats.py,sha256=mbhwsyIqt5upsSD346qGjdCw7CFBa0tIS7zHU9e0jNI,9536
30
- spacr/submodules.py,sha256=jFlJeVNuIEf63TtCOpTlOZ4iiSLr238kRBiGAAAgKE4,67626
31
- spacr/timelapse.py,sha256=KGfG4L4-QnFfgbF7L6C5wL_3gd_rqr05Foje6RsoTBg,39603
32
- spacr/toxo.py,sha256=TmuhejSIPLBvsgeblsUgSvBFCR1gOkApyTKidooJ5Us,26044
33
- spacr/utils.py,sha256=Cyy0pS-dwvMbH8cn6gu8OG1C-Kg6yUOAEacng-vkDgk,228837
30
+ spacr/submodules.py,sha256=dNiUqwDYwJ2J1s3DkwGLOTB-TzyGq_GXoojpCrLMm7A,82812
31
+ spacr/timelapse.py,sha256=lh3Aev5S7Ou1YWPBYBYeSGU0I-NPb0-4znYfm2NYf_I,39629
32
+ spacr/toxo.py,sha256=GoNfgyH-NJx3WOzNQPgzODir7Jp65fs7UM46XpzcrUo,26056
33
+ spacr/utils.py,sha256=20FRbevoFmPA61vS50tR48g6DpGkIvInGPv9nE810gQ,231668
34
34
  spacr/version.py,sha256=axH5tnGwtgSnJHb5IDhiu4Zjk5GhLyAEDRe-rnaoFOA,409
35
35
  spacr/resources/MEDIAR/.gitignore,sha256=Ff1q9Nme14JUd-4Q3jZ65aeQ5X4uttptssVDgBVHYo8,152
36
36
  spacr/resources/MEDIAR/LICENSE,sha256=yEj_TRDLUfDpHDNM0StALXIt6mLqSgaV2hcCwa6_TcY,1065
@@ -153,9 +153,9 @@ spacr/resources/icons/umap.png,sha256=dOLF3DeLYy9k0nkUybiZMe1wzHQwLJFRmgccppw-8b
153
153
  spacr/resources/images/plate1_E01_T0001F001L01A01Z01C02.tif,sha256=Tl0ZUfZ_AYAbu0up_nO0tPRtF1BxXhWQ3T3pURBCCRo,7958528
154
154
  spacr/resources/images/plate1_E01_T0001F001L01A02Z01C01.tif,sha256=m8N-V71rA1TT4dFlENNg8s0Q0YEXXs8slIn7yObmZJQ,7958528
155
155
  spacr/resources/images/plate1_E01_T0001F001L01A03Z01C03.tif,sha256=Pbhk7xn-KUP6RSIhJsxQcrHFImBm3GEpLkzx7WOc-5M,7958528
156
- spacr-0.4.15.dist-info/LICENSE,sha256=SR-2MeGc6SCM1UORJYyarSWY_A-JaOMFDj7ReSs9tRM,1083
157
- spacr-0.4.15.dist-info/METADATA,sha256=S7GQ5vQOQmp_uZPNThj1d29xrjSf_joXTOUVX96UDCY,6073
158
- spacr-0.4.15.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
159
- spacr-0.4.15.dist-info/entry_points.txt,sha256=BMC0ql9aNNpv8lUZ8sgDLQMsqaVnX5L535gEhKUP5ho,296
160
- spacr-0.4.15.dist-info/top_level.txt,sha256=GJPU8FgwRXGzKeut6JopsSRY2R8T3i9lDgya42tLInY,6
161
- spacr-0.4.15.dist-info/RECORD,,
156
+ spacr-0.4.60.dist-info/LICENSE,sha256=SR-2MeGc6SCM1UORJYyarSWY_A-JaOMFDj7ReSs9tRM,1083
157
+ spacr-0.4.60.dist-info/METADATA,sha256=Na4GGSJEuobmjgAo8HSbejQ0h8E1etVHb249v5oBB6Y,6096
158
+ spacr-0.4.60.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
159
+ spacr-0.4.60.dist-info/entry_points.txt,sha256=BMC0ql9aNNpv8lUZ8sgDLQMsqaVnX5L535gEhKUP5ho,296
160
+ spacr-0.4.60.dist-info/top_level.txt,sha256=GJPU8FgwRXGzKeut6JopsSRY2R8T3i9lDgya42tLInY,6
161
+ spacr-0.4.60.dist-info/RECORD,,
File without changes