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/core.py +52 -9
- spacr/deep_spacr.py +2 -3
- spacr/gui_core.py +247 -41
- spacr/gui_elements.py +133 -2
- spacr/gui_utils.py +17 -15
- spacr/io.py +540 -55
- spacr/ml.py +141 -258
- spacr/plot.py +76 -34
- spacr/sequencing.py +73 -38
- spacr/settings.py +136 -128
- spacr/submodules.py +619 -213
- spacr/timelapse.py +25 -25
- spacr/toxo.py +23 -23
- spacr/utils.py +162 -89
- {spacr-0.4.15.dist-info → spacr-0.4.60.dist-info}/METADATA +2 -1
- {spacr-0.4.15.dist-info → spacr-0.4.60.dist-info}/RECORD +20 -20
- {spacr-0.4.15.dist-info → spacr-0.4.60.dist-info}/LICENSE +0 -0
- {spacr-0.4.15.dist-info → spacr-0.4.60.dist-info}/WHEEL +0 -0
- {spacr-0.4.15.dist-info → spacr-0.4.60.dist-info}/entry_points.txt +0 -0
- {spacr-0.4.15.dist-info → spacr-0.4.60.dist-info}/top_level.txt +0 -0
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 = ['
|
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 = ['
|
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 = ['
|
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
|
-
|
326
|
-
if show:
|
327
|
-
display(settings_df)
|
324
|
+
settings_2 = settings.copy()
|
328
325
|
|
329
|
-
if isinstance(
|
330
|
-
src =
|
326
|
+
if isinstance(settings_2['src'], list):
|
327
|
+
src = settings_2['src'][0]
|
331
328
|
name = f"{name}_list"
|
332
329
|
else:
|
333
|
-
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['
|
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['
|
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_ = '
|
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[['
|
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[['
|
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', '
|
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', '
|
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', '
|
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 '
|
1313
|
+
"""Determine if a value maps to 'rowID' or 'columnID'."""
|
1343
1314
|
if isinstance(val, str) and val.startswith('c'):
|
1344
|
-
return '
|
1315
|
+
return 'columnID'
|
1345
1316
|
elif isinstance(val, str) and val.startswith('r'):
|
1346
|
-
return '
|
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['
|
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(['
|
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[['
|
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['
|
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', '
|
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 == '
|
3124
|
-
regex = f'(?P<plateID>.*)_(?P<wellID>.*)_T(?P<timeID>.*)F(?P<fieldID>.*)L(?P<laserID
|
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['
|
4718
|
-
df['
|
4719
|
-
df['
|
4720
|
-
df['
|
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['
|
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': '
|
5103
|
+
df = df.rename(columns={'plate_name': 'plateID'})
|
5138
5104
|
if 'column_name' in df.columns:
|
5139
|
-
df = df.rename(columns={'column_name': '
|
5105
|
+
df = df.rename(columns={'column_name': 'columnID'})
|
5140
5106
|
if 'col' in df.columns:
|
5141
|
-
df = df.rename(columns={'col': '
|
5107
|
+
df = df.rename(columns={'col': 'columnID'})
|
5142
5108
|
if 'row_name' in df.columns:
|
5143
|
-
df = df.rename(columns={'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[['
|
5113
|
+
df[['plateID', 'rowID']] = df['plate_row'].str.split('_', expand=True)
|
5148
5114
|
return df
|
5149
5115
|
|
5150
|
-
def control_filelist(folder, mode='
|
5116
|
+
def control_filelist(folder, mode='columnID', values=['01','02']):
|
5151
5117
|
files = os.listdir(folder)
|
5152
|
-
if mode is '
|
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 '
|
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 '
|
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'] = '
|
5141
|
+
columns_to_rename['row'] = 'rowID'
|
5176
5142
|
if 'col' in column_names:
|
5177
|
-
columns_to_rename['col'] = '
|
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.
|
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=
|
13
|
-
spacr/deep_spacr.py,sha256=
|
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=
|
16
|
-
spacr/gui_elements.py,sha256=
|
17
|
-
spacr/gui_utils.py,sha256=
|
18
|
-
spacr/io.py,sha256=
|
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=
|
22
|
+
spacr/ml.py,sha256=XCRZeX7UkbMctQICIoskeWVx8CCmmCoHNauUOAkfFq0,91692
|
23
23
|
spacr/openai.py,sha256=5vBZ3Jl2llYcW3oaTEXgdyCB2aJujMUIO5K038z7w_A,1246
|
24
|
-
spacr/plot.py,sha256=
|
25
|
-
spacr/sequencing.py,sha256=
|
26
|
-
spacr/settings.py,sha256=
|
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=
|
31
|
-
spacr/timelapse.py,sha256=
|
32
|
-
spacr/toxo.py,sha256=
|
33
|
-
spacr/utils.py,sha256=
|
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.
|
157
|
-
spacr-0.4.
|
158
|
-
spacr-0.4.
|
159
|
-
spacr-0.4.
|
160
|
-
spacr-0.4.
|
161
|
-
spacr-0.4.
|
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
|
File without changes
|
File without changes
|
File without changes
|