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/settings.py
CHANGED
@@ -26,12 +26,14 @@ def set_default_plot_merge_settings():
|
|
26
26
|
|
27
27
|
def set_default_settings_preprocess_generate_masks(settings={}):
|
28
28
|
|
29
|
+
settings.setdefault('denoise', False)
|
29
30
|
settings.setdefault('src', 'path')
|
30
31
|
settings.setdefault('delete_intermediate', False)
|
31
32
|
settings.setdefault('segmentation_mode', 'cellpose')
|
32
33
|
settings.setdefault('preprocess', True)
|
33
34
|
settings.setdefault('masks', True)
|
34
35
|
settings.setdefault('save', True)
|
36
|
+
settings.setdefault('consolidate', False)
|
35
37
|
settings.setdefault('batch_size', 50)
|
36
38
|
settings.setdefault('test_mode', False)
|
37
39
|
settings.setdefault('test_images', 10)
|
@@ -86,7 +88,7 @@ def set_default_settings_preprocess_generate_masks(settings={}):
|
|
86
88
|
settings.setdefault('fps', 2)
|
87
89
|
settings.setdefault('timelapse_displacement', None)
|
88
90
|
settings.setdefault('timelapse_memory', 3)
|
89
|
-
settings.setdefault('timelapse_frame_limits', [5,
|
91
|
+
settings.setdefault('timelapse_frame_limits', [5,])
|
90
92
|
settings.setdefault('timelapse_remove_transient', False)
|
91
93
|
settings.setdefault('timelapse_mode', 'trackpy')
|
92
94
|
settings.setdefault('timelapse_objects', None)
|
@@ -219,7 +221,7 @@ def set_default_umap_image_settings(settings={}):
|
|
219
221
|
settings.setdefault('smooth_lines', True)
|
220
222
|
settings.setdefault('clustering', 'dbscan')
|
221
223
|
settings.setdefault('exclude', None)
|
222
|
-
settings.setdefault('col_to_compare', '
|
224
|
+
settings.setdefault('col_to_compare', 'columnID')
|
223
225
|
settings.setdefault('pos', 'c1')
|
224
226
|
settings.setdefault('neg', 'c2')
|
225
227
|
settings.setdefault('mix', 'c3')
|
@@ -301,76 +303,6 @@ def get_measure_crop_settings(settings={}):
|
|
301
303
|
print(f'Test mode enabled with {test_imgs} images, plotting set to True')
|
302
304
|
|
303
305
|
return settings
|
304
|
-
settings.setdefault('normalize_by','png')
|
305
|
-
settings.setdefault('crop_mode',['cell'])
|
306
|
-
settings.setdefault('dialate_pngs', False)
|
307
|
-
settings.setdefault('dialate_png_ratios', [0.2])
|
308
|
-
|
309
|
-
# Timelapsed settings
|
310
|
-
settings.setdefault('timelapse', False)
|
311
|
-
settings.setdefault('timelapse_objects', 'cell')
|
312
|
-
|
313
|
-
# Operational settings
|
314
|
-
settings.setdefault('plot',False)
|
315
|
-
settings.setdefault('n_jobs', os.cpu_count()-2)
|
316
|
-
|
317
|
-
# Object settings
|
318
|
-
settings.setdefault('cell_mask_dim',4)
|
319
|
-
settings.setdefault('nucleus_mask_dim',5)
|
320
|
-
settings.setdefault('pathogen_mask_dim',6)
|
321
|
-
settings.setdefault('cytoplasm',False)
|
322
|
-
settings.setdefault('uninfected',True)
|
323
|
-
settings.setdefault('cell_min_size',0)
|
324
|
-
settings.setdefault('nucleus_min_size',0)
|
325
|
-
settings.setdefault('pathogen_min_size',0)
|
326
|
-
settings.setdefault('cytoplasm_min_size',0)
|
327
|
-
settings.setdefault('merge_edge_pathogen_cells', True)
|
328
|
-
|
329
|
-
if settings['test_mode']:
|
330
|
-
settings['verbose'] = True
|
331
|
-
settings['plot'] = True
|
332
|
-
test_imgs = settings['test_nr']
|
333
|
-
print(f'Test mode enabled with {test_imgs} images, plotting set to True')
|
334
|
-
|
335
|
-
return settings
|
336
|
-
settings.setdefault('save_arrays', False)
|
337
|
-
settings.setdefault('save_png',True)
|
338
|
-
settings.setdefault('use_bounding_box',False)
|
339
|
-
settings.setdefault('png_size',[224,224])
|
340
|
-
settings.setdefault('png_dims',[0,1,2])
|
341
|
-
settings.setdefault('normalize',False)
|
342
|
-
settings.setdefault('normalize_by','png')
|
343
|
-
settings.setdefault('crop_mode',['cell'])
|
344
|
-
settings.setdefault('dialate_pngs', False)
|
345
|
-
settings.setdefault('dialate_png_ratios', [0.2])
|
346
|
-
|
347
|
-
# Timelapsed settings
|
348
|
-
settings.setdefault('timelapse', False)
|
349
|
-
settings.setdefault('timelapse_objects', 'cell')
|
350
|
-
|
351
|
-
# Operational settings
|
352
|
-
settings.setdefault('plot',False)
|
353
|
-
settings.setdefault('n_jobs', os.cpu_count()-2)
|
354
|
-
|
355
|
-
# Object settings
|
356
|
-
settings.setdefault('cell_mask_dim',4)
|
357
|
-
settings.setdefault('nucleus_mask_dim',5)
|
358
|
-
settings.setdefault('pathogen_mask_dim',6)
|
359
|
-
settings.setdefault('cytoplasm',False)
|
360
|
-
settings.setdefault('uninfected',True)
|
361
|
-
settings.setdefault('cell_min_size',0)
|
362
|
-
settings.setdefault('nucleus_min_size',0)
|
363
|
-
settings.setdefault('pathogen_min_size',0)
|
364
|
-
settings.setdefault('cytoplasm_min_size',0)
|
365
|
-
settings.setdefault('merge_edge_pathogen_cells', True)
|
366
|
-
|
367
|
-
if settings['test_mode']:
|
368
|
-
settings['verbose'] = True
|
369
|
-
settings['plot'] = True
|
370
|
-
test_imgs = settings['test_nr']
|
371
|
-
print(f'Test mode enabled with {test_imgs} images, plotting set to True')
|
372
|
-
|
373
|
-
return settings
|
374
306
|
|
375
307
|
def set_default_analyze_screen(settings):
|
376
308
|
settings.setdefault('src', 'path')
|
@@ -388,7 +320,7 @@ def set_default_analyze_screen(settings):
|
|
388
320
|
settings.setdefault('learning_rate',0.001)
|
389
321
|
settings.setdefault('n_estimators',1000)
|
390
322
|
settings.setdefault('test_size',0.2)
|
391
|
-
settings.setdefault('location_column','
|
323
|
+
settings.setdefault('location_column','columnID')
|
392
324
|
settings.setdefault('positive_control','c2')
|
393
325
|
settings.setdefault('negative_control','c1')
|
394
326
|
settings.setdefault('exclude',None)
|
@@ -451,7 +383,7 @@ def set_generate_training_dataset_defaults(settings):
|
|
451
383
|
settings.setdefault('size',224)
|
452
384
|
settings.setdefault('test_split',0.1)
|
453
385
|
settings.setdefault('class_metadata',[['c1'],['c2']])
|
454
|
-
settings.setdefault('metadata_type_by','
|
386
|
+
settings.setdefault('metadata_type_by','columnID')
|
455
387
|
settings.setdefault('channel_of_interest',3)
|
456
388
|
settings.setdefault('custom_measurement',None)
|
457
389
|
settings.setdefault('tables',None)
|
@@ -473,7 +405,7 @@ def deep_spacr_defaults(settings):
|
|
473
405
|
settings.setdefault('size',224)
|
474
406
|
settings.setdefault('test_split',0.1)
|
475
407
|
settings.setdefault('class_metadata',[['c1'],['c2']])
|
476
|
-
settings.setdefault('metadata_type_by','
|
408
|
+
settings.setdefault('metadata_type_by','columnID')
|
477
409
|
settings.setdefault('channel_of_interest',3)
|
478
410
|
settings.setdefault('custom_measurement',None)
|
479
411
|
settings.setdefault('tables',None)
|
@@ -557,7 +489,7 @@ def get_analyze_recruitment_default_settings(settings):
|
|
557
489
|
settings.setdefault('pathogen_plate_metadata',[['c1', 'c2', 'c3'],['c4','c5', 'c6']])
|
558
490
|
settings.setdefault('treatments',['cm', 'lovastatin'])
|
559
491
|
settings.setdefault('treatment_plate_metadata',[['r1', 'r2','r3'], ['r4', 'r5','r6']])
|
560
|
-
#settings.setdefault('metadata_types',['
|
492
|
+
#settings.setdefault('metadata_types',['columnID', 'columnID', 'rowID'])
|
561
493
|
settings.setdefault('channel_dims',[0,1,2,3])
|
562
494
|
settings.setdefault('cell_chann_dim',3)
|
563
495
|
settings.setdefault('cell_mask_dim',4)
|
@@ -579,7 +511,40 @@ def get_analyze_recruitment_default_settings(settings):
|
|
579
511
|
settings.setdefault('pathogen_intensity_range',[0,100000])
|
580
512
|
settings.setdefault('nucleus_intensity_range',[0,100000])
|
581
513
|
settings.setdefault('cell_intensity_range',[0,100000])
|
582
|
-
settings.setdefault('target_intensity_min',
|
514
|
+
settings.setdefault('target_intensity_min',1)
|
515
|
+
return settings
|
516
|
+
|
517
|
+
def get_default_test_cellpose_model_settings(settings):
|
518
|
+
settings.setdefault('src','path')
|
519
|
+
settings.setdefault('model_path','path')
|
520
|
+
settings.setdefault('save',True)
|
521
|
+
settings.setdefault('normalize',True)
|
522
|
+
settings.setdefault('percentiles',(2,98))
|
523
|
+
settings.setdefault('batch_size',50)
|
524
|
+
settings.setdefault('CP_probability',0)
|
525
|
+
settings.setdefault('FT',100)
|
526
|
+
settings.setdefault('target_size',1000)
|
527
|
+
return settings
|
528
|
+
|
529
|
+
def get_default_apply_cellpose_model_settings(settings):
|
530
|
+
settings.setdefault('src','path')
|
531
|
+
settings.setdefault('model_path','path')
|
532
|
+
settings.setdefault('save',True)
|
533
|
+
settings.setdefault('normalize',True)
|
534
|
+
settings.setdefault('percentiles',(2,98))
|
535
|
+
settings.setdefault('batch_size',50)
|
536
|
+
settings.setdefault('CP_probability',0)
|
537
|
+
settings.setdefault('FT',100)
|
538
|
+
settings.setdefault('circularize',False)
|
539
|
+
settings.setdefault('target_size',1000)
|
540
|
+
return settings
|
541
|
+
|
542
|
+
def default_settings_analyze_percent_positive(settings):
|
543
|
+
settings.setdefault('src','path')
|
544
|
+
settings.setdefault('tables',['cell'])
|
545
|
+
settings.setdefault('filter_1',['cell_area',1000])
|
546
|
+
settings.setdefault('value_col','cell_channel_2_mean_intensity')
|
547
|
+
settings.setdefault('threshold',2000)
|
583
548
|
return settings
|
584
549
|
|
585
550
|
def get_analyze_reads_default_settings(settings):
|
@@ -654,9 +619,8 @@ def get_perform_regression_default_settings(settings):
|
|
654
619
|
settings.setdefault('cov_type',None)
|
655
620
|
settings.setdefault('alpha',1)
|
656
621
|
settings.setdefault('filter_value',['c1', 'c2', 'c3'])
|
657
|
-
settings.setdefault('filter_column','
|
658
|
-
settings.setdefault('
|
659
|
-
settings.setdefault('class_1_threshold',None)
|
622
|
+
settings.setdefault('filter_column','columnID')
|
623
|
+
settings.setdefault('plateID','plate1')
|
660
624
|
settings.setdefault('metadata_files',['/home/carruthers/Documents/TGGT1_Summary.csv','/home/carruthers/Documents/TGME49_Summary.csv'])
|
661
625
|
settings.setdefault('volcano','gene')
|
662
626
|
settings.setdefault('toxo', True)
|
@@ -925,6 +889,7 @@ expected_types = {
|
|
925
889
|
"agg_type": str,
|
926
890
|
"min_cell_count": int,
|
927
891
|
"resize": bool,
|
892
|
+
"denoise":bool,
|
928
893
|
"target_height": (int, type(None)),
|
929
894
|
"target_width": (int, type(None)),
|
930
895
|
"rescale": bool,
|
@@ -1017,12 +982,13 @@ expected_types = {
|
|
1017
982
|
"flow_threshold":float,
|
1018
983
|
"cell_diamiter":int,
|
1019
984
|
"nucleus_diamiter":int,
|
1020
|
-
"pathogen_diamiter":int
|
985
|
+
"pathogen_diamiter":int,
|
986
|
+
"consolidate":bool
|
1021
987
|
}
|
1022
988
|
|
1023
989
|
categories = {"Paths":[ "src", "grna", "barcodes", "custom_model_path", "dataset","model_path","grna_csv","row_csv","column_csv", "metadata_files", "score_data","count_data"],
|
1024
990
|
"General": ["cell_mask_dim", "cytoplasm", "cell_chann_dim", "cell_channel", "nucleus_chann_dim", "nucleus_channel", "nucleus_mask_dim", "pathogen_mask_dim", "pathogen_chann_dim", "pathogen_channel", "test_mode", "plot", "metadata_type", "custom_regex", "experiment", "channels", "magnification", "channel_dims", "apply_model_to_dataset", "generate_training_dataset", "train_DL_model", "segmentation_mode", "delete_intermediate", "uninfected", ],
|
1025
|
-
"Cellpose":["fill_in","from_scratch", "n_epochs", "width_height", "model_name", "custom_model", "resample", "rescale", "CP_prob", "flow_threshold", "percentiles", "invert", "diameter", "grayscale", "Signal_to_noise", "resize", "target_height", "target_width"],
|
991
|
+
"Cellpose":["denoise","fill_in","from_scratch", "n_epochs", "width_height", "model_name", "custom_model", "resample", "rescale", "CP_prob", "flow_threshold", "percentiles", "invert", "diameter", "grayscale", "Signal_to_noise", "resize", "target_height", "target_width"],
|
1026
992
|
"Cell": ["cell_diamiter","cell_intensity_range", "cell_size_range", "cell_background", "cell_Signal_to_noise", "cell_CP_prob", "cell_FT", "remove_background_cell", "cell_min_size", "cytoplasm_min_size", "adjust_cells", "cells", "cell_loc"],
|
1027
993
|
"Nucleus": ["nucleus_diamiter","nucleus_intensity_range", "nucleus_size_range", "nucleus_background", "nucleus_Signal_to_noise", "nucleus_CP_prob", "nucleus_FT", "remove_background_nucleus", "nucleus_min_size", "nucleus_loc"],
|
1028
994
|
"Pathogen": ["pathogen_diamiter","pathogen_intensity_range", "pathogen_size_range", "pathogen_background", "pathogen_Signal_to_noise", "pathogen_CP_prob", "pathogen_FT", "pathogen_model", "remove_background_pathogen", "pathogen_min_size", "pathogens", "pathogen_loc", "pathogen_types", "pathogen_plate_metadata", ],
|
@@ -1033,13 +999,13 @@ categories = {"Paths":[ "src", "grna", "barcodes", "custom_model_path", "dataset
|
|
1033
999
|
"Hyperparamiters (Training)": ["png_type", "score_threshold","file_type", "train_channels", "epochs", "loss_type", "optimizer_type","image_size","val_split","learning_rate","weight_decay","dropout_rate", "init_weights", "train", "classes", "augment", "amsgrad","use_checkpoint","gradient_accumulation","gradient_accumulation_steps","intermedeate_save","pin_memory"],
|
1034
1000
|
"Hyperparamiters (Embedding)": ["visualize","n_neighbors","min_dist","metric","resnet_features","reduction_method","embedding_by_controls","col_to_compare","log_data"],
|
1035
1001
|
"Hyperparamiters (Clustering)": ["eps","min_samples","analyze_clusters","clustering","remove_cluster_noise"],
|
1036
|
-
"Hyperparamiters (Regression)":["cross_validation","prune_features","reg_lambda","reg_alpha","cov_type", "
|
1002
|
+
"Hyperparamiters (Regression)":["cross_validation","prune_features","reg_lambda","reg_alpha","cov_type", "plate", "other", "fraction_threshold", "alpha", "random_row_column_effects", "regression_type", "min_cell_count", "agg_type", "transform", "dependent_variable"],
|
1037
1003
|
"Hyperparamiters (Activation)":["cam_type", "overlay", "correlation", "target_layer", "normalize_input"],
|
1038
1004
|
"Annotation": ["filter_column", "filter_value","volcano", "toxo", "controls", "nc_loc", "pc_loc", "nc", "pc", "cell_plate_metadata","treatment_plate_metadata", "metadata_types", "cell_types", "target","positive_control","negative_control", "location_column", "treatment_loc", "channel_of_interest", "measurement", "treatments", "um_per_pixel", "nr_imgs", "exclude", "exclude_conditions", "mix", "pos", "neg"],
|
1039
1005
|
"Plot": ["split_axis_lims", "x_lim","log_x","log_y", "plot_control", "plot_nr", "examples_to_plot", "normalize_plots", "cmap", "figuresize", "plot_cluster_grids", "img_zoom", "row_limit", "color_by", "plot_images", "smooth_lines", "plot_points", "plot_outlines", "black_background", "plot_by_cluster", "heatmap_feature","grouping","min_max","cmap","save_figure"],
|
1040
1006
|
"Timelapse": ["timelapse", "fps", "timelapse_displacement", "timelapse_memory", "timelapse_frame_limits", "timelapse_remove_transient", "timelapse_mode", "timelapse_objects", "compartments"],
|
1041
1007
|
"Advanced": ["merge_edge_pathogen_cells", "test_images", "random_test", "test_nr", "test", "test_split", "normalize", "target_unique_count","threshold_multiplier", "threshold_method", "min_n","shuffle", "target_intensity_min", "cells_per_well", "nuclei_limit", "pathogen_limit", "background", "backgrounds", "schedule", "test_size","exclude","n_repeats","top_features", "model_type_ml", "model_type","minimum_cell_count","n_estimators","preprocess", "remove_background", "normalize", "lower_percentile", "merge_pathogens", "batch_size", "filter", "save", "masks", "verbose", "randomize", "n_jobs"],
|
1042
|
-
"Beta": ["all_to_mip", "pick_slice", "skip_mode", "upscale", "upscale_factor"]
|
1008
|
+
"Beta": ["all_to_mip", "pick_slice", "skip_mode", "upscale", "upscale_factor", "consolidate"]
|
1043
1009
|
}
|
1044
1010
|
|
1045
1011
|
|
@@ -1053,38 +1019,38 @@ def check_settings(vars_dict, expected_types, q=None):
|
|
1053
1019
|
q = Queue()
|
1054
1020
|
|
1055
1021
|
settings = {}
|
1022
|
+
errors = [] # Collect errors instead of stopping at the first one
|
1056
1023
|
|
1057
1024
|
for key, (label, widget, var, _) in vars_dict.items():
|
1058
|
-
if key not in expected_types:
|
1059
|
-
|
1060
|
-
|
1061
|
-
continue
|
1025
|
+
if key not in expected_types and key not in category_keys:
|
1026
|
+
errors.append(f"Warning: Key '{key}' not found in expected types.")
|
1027
|
+
continue
|
1062
1028
|
|
1063
|
-
value = var.get()
|
1029
|
+
value = var.get()
|
1064
1030
|
if value in ['None', '']:
|
1065
1031
|
value = None
|
1066
1032
|
|
1067
1033
|
expected_type = expected_types.get(key, str)
|
1068
1034
|
|
1069
1035
|
try:
|
1070
|
-
#if key in ["cell_plate_metadata", "timelapse_frame_limits", "png_size", "pathogen_loc", "treatment_loc", "pathogen_plate_metadata", "treatment_plate_metadata", "barcode_coordinates", "class_metadata"]:
|
1071
1036
|
if key in ["cell_plate_metadata", "timelapse_frame_limits", "png_size", "png_dims", "pathogen_plate_metadata", "treatment_plate_metadata", "class_metadata", "crop_mode"]:
|
1072
|
-
|
1073
1037
|
if value is None:
|
1074
|
-
|
1038
|
+
parsed_value = None
|
1075
1039
|
else:
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1040
|
+
try:
|
1041
|
+
parsed_value = ast.literal_eval(value)
|
1042
|
+
except (ValueError, SyntaxError):
|
1043
|
+
raise ValueError(f"Expected a list or list of lists but got an invalid format: {value}")
|
1044
|
+
|
1080
1045
|
if isinstance(parsed_value, list):
|
1081
1046
|
if all(isinstance(i, list) for i in parsed_value) or all(not isinstance(i, list) for i in parsed_value):
|
1082
1047
|
settings[key] = parsed_value
|
1083
1048
|
else:
|
1084
|
-
raise ValueError("Invalid format:
|
1049
|
+
raise ValueError(f"Invalid format: '{key}' contains mixed types (single values and lists).")
|
1050
|
+
|
1085
1051
|
else:
|
1086
|
-
raise ValueError("
|
1087
|
-
|
1052
|
+
raise ValueError(f"Expected a list for '{key}', but got {type(parsed_value).__name__}.")
|
1053
|
+
|
1088
1054
|
elif expected_type == list:
|
1089
1055
|
settings[key] = parse_list(value) if value else None
|
1090
1056
|
|
@@ -1092,37 +1058,52 @@ def check_settings(vars_dict, expected_types, q=None):
|
|
1092
1058
|
settings[key] = settings[key][0]
|
1093
1059
|
|
1094
1060
|
elif expected_type == bool:
|
1095
|
-
settings[key] = value
|
1061
|
+
settings[key] = value.lower() in ['true', '1', 't', 'y', 'yes'] if isinstance(value, str) else bool(value)
|
1062
|
+
|
1096
1063
|
elif expected_type == (int, type(None)):
|
1097
|
-
|
1064
|
+
if value is None or str(value).isdigit():
|
1065
|
+
settings[key] = int(value) if value is not None else None
|
1066
|
+
else:
|
1067
|
+
raise ValueError(f"Expected an integer or None for '{key}', but got '{value}'.")
|
1068
|
+
|
1098
1069
|
elif expected_type == (float, type(None)):
|
1099
|
-
|
1070
|
+
if value is None or (isinstance(value, str) and value.replace(".", "", 1).isdigit()):
|
1071
|
+
settings[key] = float(value) if value is not None else None
|
1072
|
+
else:
|
1073
|
+
raise ValueError(f"Expected a float or None for '{key}', but got '{value}'.")
|
1074
|
+
|
1100
1075
|
elif expected_type == (int, float):
|
1101
|
-
|
1076
|
+
try:
|
1077
|
+
settings[key] = float(value) if '.' in str(value) else int(value)
|
1078
|
+
except ValueError:
|
1079
|
+
raise ValueError(f"Expected an integer or float for '{key}', but got '{value}'.")
|
1080
|
+
|
1102
1081
|
elif expected_type == (str, type(None)):
|
1103
|
-
settings[key] = str(value) if value else None
|
1082
|
+
settings[key] = str(value) if value is not None else None
|
1083
|
+
|
1104
1084
|
elif expected_type == (str, type(None), list):
|
1105
1085
|
if isinstance(value, list):
|
1106
1086
|
settings[key] = parse_list(value) if value else None
|
1107
1087
|
elif isinstance(value, str):
|
1108
|
-
settings[key] = str(value)
|
1088
|
+
settings[key] = str(value)
|
1109
1089
|
else:
|
1110
1090
|
settings[key] = None
|
1111
1091
|
|
1112
1092
|
elif expected_type == dict:
|
1113
1093
|
try:
|
1114
|
-
# Ensure that the value is a string that can be converted to a dictionary
|
1115
1094
|
if isinstance(value, str):
|
1116
|
-
|
1095
|
+
parsed_dict = ast.literal_eval(value)
|
1117
1096
|
else:
|
1118
1097
|
raise ValueError("Expected a string representation of a dictionary.")
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1098
|
+
|
1099
|
+
if not isinstance(parsed_dict, dict):
|
1100
|
+
raise ValueError(f"Expected a dictionary for '{key}', but got {type(parsed_dict).__name__}.")
|
1101
|
+
|
1102
|
+
settings[key] = parsed_dict
|
1123
1103
|
except (ValueError, SyntaxError) as e:
|
1124
1104
|
settings[key] = {}
|
1125
|
-
|
1105
|
+
errors.append(f"Error: Invalid dictionary format for '{key}'. Expected type: dict. Error: {e}")
|
1106
|
+
|
1126
1107
|
elif isinstance(expected_type, tuple):
|
1127
1108
|
for typ in expected_type:
|
1128
1109
|
try:
|
@@ -1131,15 +1112,25 @@ def check_settings(vars_dict, expected_types, q=None):
|
|
1131
1112
|
except (ValueError, TypeError):
|
1132
1113
|
continue
|
1133
1114
|
else:
|
1134
|
-
raise ValueError
|
1115
|
+
raise ValueError(f"Value '{value}' for '{key}' does not match any expected types: {expected_type}.")
|
1116
|
+
|
1135
1117
|
else:
|
1136
|
-
|
1118
|
+
try:
|
1119
|
+
settings[key] = expected_type(value) if value else None
|
1120
|
+
except (ValueError, TypeError):
|
1121
|
+
raise ValueError(f"Expected type {expected_type.__name__} for '{key}', but got '{value}'.")
|
1122
|
+
|
1137
1123
|
except (ValueError, SyntaxError) as e:
|
1138
1124
|
expected_type_name = ' or '.join([t.__name__ for t in expected_type]) if isinstance(expected_type, tuple) else expected_type.__name__
|
1139
|
-
|
1140
|
-
return
|
1125
|
+
errors.append(f"Error: '{key}' has invalid format. Expected type: {expected_type_name}. Got value: '{value}'. Error: {e}")
|
1141
1126
|
|
1142
|
-
|
1127
|
+
# Send all collected errors to the queue
|
1128
|
+
for error in errors:
|
1129
|
+
q.put(error)
|
1130
|
+
|
1131
|
+
|
1132
|
+
|
1133
|
+
return settings, errors
|
1143
1134
|
|
1144
1135
|
def generate_fields(variables, scrollable_frame):
|
1145
1136
|
from .gui_utils import create_input_field
|
@@ -1164,16 +1155,25 @@ def generate_fields(variables, scrollable_frame):
|
|
1164
1155
|
"black_background": "(bool) - Whether to use a black background for plots.",
|
1165
1156
|
"calculate_correlation": "(bool) - Whether to calculate correlations between features.",
|
1166
1157
|
"cell_CP_prob": "(float) - The cellpose probability threshold for the cell channel. This will be used in cell segmentation.",
|
1158
|
+
"nucleus_CP_prob": "(float) - The cellpose probability threshold for the nucleus channel. This will be used in cell segmentation.",
|
1159
|
+
"pathogen_CP_prob": "(float) - The cellpose probability threshold for the pathogen channel. This will be used in cell segmentation.",
|
1167
1160
|
"cell_FT": "(float) - The flow threshold for cell objects. This will be used to segment the cells.",
|
1168
|
-
"
|
1161
|
+
"nucleus_FT": "(float) - The flow threshold for nucleus objects. This will be used to segment the cells.",
|
1162
|
+
"pathogen_FT": "(float) - The flow threshold for pathogen objects. This will be used to segment the cells.",
|
1163
|
+
"cell_background": "(int) - The background intensity for the cell channel. This will be used to remove background noise.",
|
1164
|
+
"nucleus_background": "(int) - The background intensity for the nucleus channel. This will be used to remove background noise.",
|
1165
|
+
"pathogen_background": "(int) - The background intensity for the pathogen channel. This will be used to remove background noise.",
|
1169
1166
|
"cell_chann_dim": "(int) - Dimension of the channel to use for cell segmentation.",
|
1170
|
-
"cell_channel": "(int) - The channel to use for
|
1167
|
+
"cell_channel": "(int) - The channel to use for generatin cell masks. If None, cell masks will not be generated.",
|
1168
|
+
"nucleus_channel": "(int) - The channel to use for generatin nucleus masks. If None, nucleus masks will not be generated.",
|
1169
|
+
"pathogen_channel": "(int) - The channel to use for generatin pathogen masks. If None, pathogen masks will not be generated.",
|
1171
1170
|
"cell_intensity_range": "(list) - Intensity range for cell segmentation.",
|
1172
1171
|
"cell_loc": "(list) - The locations of the cell types in the images.",
|
1173
|
-
"cell_mask_dim": "(int) - The dimension of the array the cell mask is saved in.",
|
1172
|
+
"cell_mask_dim": "(int) - The dimension of the array the cell mask is saved in (array order:channels,cell, nucleus, pathogen, cytoplasm) array starts at dimension 0.",
|
1173
|
+
"nucleus_mask_dim": "(int) - The dimension of the array the nucleus mask is saved in (array order:channels,cell, nucleus, pathogen, cytoplasm) array starts at dimension 0.",
|
1174
1174
|
"cell_min_size": "(int) - The minimum size of cell objects in pixels^2.",
|
1175
1175
|
"cell_plate_metadata": "(str) - Metadata for the cell plate.",
|
1176
|
-
"cell_Signal_to_noise": "(
|
1176
|
+
"cell_Signal_to_noise": "(int) - The signal-to-noise ratio for the cell channel. This will be used to determine the range of intensities to normalize images to for cell segmentation.",
|
1177
1177
|
"cell_size_range": "(list) - Size range for cell segmentation.",
|
1178
1178
|
"cell_types": "(list) - Types of cells to include in the analysis.",
|
1179
1179
|
"cells": "(list of lists) - The cell types to include in the analysis.",
|
@@ -1188,13 +1188,17 @@ def generate_fields(variables, scrollable_frame):
|
|
1188
1188
|
"col_to_compare": "(str) - Column to compare in the embeddings.",
|
1189
1189
|
"color_by": "(str) - Coloring scheme for the plots.",
|
1190
1190
|
"compartments": "(list) - The compartments to measure in the images.",
|
1191
|
+
"consolidate": "(bool) - Consolidate image files from subfolders into one folder named consolidated.",
|
1191
1192
|
"CP_prob": "(float) - Cellpose probability threshold for segmentation.",
|
1192
1193
|
"crop_mode": "(str) - Mode to use for cropping images (cell, nucleus, pathogen, cytoplasm).",
|
1193
1194
|
"custom_model": "(str) - Path to a custom Cellpose model.",
|
1194
|
-
"custom_regex": "(str) - Custom regex pattern to extract metadata from the image names. This will only be used if 'custom' is selected for 'metadata_type'.",
|
1195
|
+
"custom_regex": "(str) - Custom regex pattern to extract metadata from the image names. This will only be used if 'custom' or 'auto' is selected for 'metadata_type'.",
|
1195
1196
|
"cytoplasm": "(bool) - Whether to segment the cytoplasm (Cell - Nucleus + Pathogen).",
|
1196
1197
|
"cytoplasm_min_size": "(int) - The minimum size of cytoplasm objects in pixels^2.",
|
1198
|
+
"nucleus_min_size": "(int) - The minimum size of nucleus objects in pixels^2.",
|
1199
|
+
"normalize_by": "(str) - Normalize cropped png images by png or by field of view.",
|
1197
1200
|
"dependent_variable": "(str) - The dependent variable for the regression analysis.",
|
1201
|
+
"delete_intermediate": "(bool) - Delete intermediate folders (stack, channel, norm_channel_stack).",
|
1198
1202
|
"diameter": "(float) - Diameter of the objects to segment.",
|
1199
1203
|
"dialate_png_ratios": "(list) - The ratios to use for dilating the PNG images. This will determine the amount of dilation applied to the images before cropping.",
|
1200
1204
|
"dialate_pngs": "(bool) - Whether to dilate the PNG images before saving.",
|
@@ -1242,7 +1246,7 @@ def generate_fields(variables, scrollable_frame):
|
|
1242
1246
|
"manders_thresholds": "(list) - Thresholds for Manders' coefficients.",
|
1243
1247
|
"mask": "(bool) - Whether to generate masks for the segmented objects. If True, masks will be generated for the nucleus, cell, and pathogen.",
|
1244
1248
|
"measurement": "(str) - The measurement to use for the analysis.",
|
1245
|
-
"metadata_type": "(str) - Type of metadata to expect in the images.
|
1249
|
+
"metadata_type": "(str) - Type of metadata to expect in the images. If 'custom' is selected, you can provide a custom regex pattern to extract metadata from the image names. auto will attempt to automatically extract metadata from the image names. cellvoyager and cq1 will use the default metadata extraction for CellVoyager and CQ1 images.",
|
1246
1250
|
"metadata_types": "(list) - Types of metadata to include in the analysis.",
|
1247
1251
|
"merge_edge_pathogen_cells": "(bool) - Whether to merge cells that share pathogen objects.",
|
1248
1252
|
"merge_pathogens": "(bool) - Whether to merge pathogen objects that share more than 75 percent of their perimeter.",
|
@@ -1263,7 +1267,8 @@ def generate_fields(variables, scrollable_frame):
|
|
1263
1267
|
"n_jobs": "(int) - The number of n_jobs to use for processing the images. This will determine how many images are processed in parallel. Increase to speed up processing.",
|
1264
1268
|
"n_neighbors": "(int) - Number of neighbors for UMAP.",
|
1265
1269
|
"n_repeats": "(int) - Number of repeats for the pathogen plate.",
|
1266
|
-
"pathogen_Signal_to_noise": "(
|
1270
|
+
"pathogen_Signal_to_noise": "(int) - The signal-to-noise ratio for the pathogen channel. This will be used to determine the range of intensities to normalize images to for pathogen segmentation.",
|
1271
|
+
"nucleus_Signal_to_noise": "(int) - The signal-to-noise ratio for the nucleus channel. This will be used to determine the range of intensities to normalize images to for nucleus segmentation.",
|
1267
1272
|
"pathogen_size_range": "(list) - Size range for pathogen segmentation.",
|
1268
1273
|
"pathogen_types": "(list) - Types of pathogens to include in the analysis.",
|
1269
1274
|
"pc": "(str) - Positive control identifier.",
|
@@ -1310,10 +1315,11 @@ def generate_fields(variables, scrollable_frame):
|
|
1310
1315
|
"save_measurements": "(bool) - Whether to save the measurements to disk.",
|
1311
1316
|
"save_png": "(bool) - Whether to save the segmented objects as PNG images.",
|
1312
1317
|
"schedule": "(str) - Schedule for processing the data.",
|
1313
|
-
"Signal_to_noise": "(
|
1318
|
+
"Signal_to_noise": "(int) - Signal-to-noise ratio for the images.",
|
1314
1319
|
"skip_mode": "(str) - The mode to use for skipping images. This will determine how to handle images that cannot be processed.",
|
1315
1320
|
"smooth_lines": "(bool) - Whether to smooth lines in the plots.",
|
1316
1321
|
"src": "(str, path) - Path to source directory.",
|
1322
|
+
"segmentation_mode": "(str) - Algorithm to use for segmentation (cellpose or mediar).",
|
1317
1323
|
"target": "(str) - Target variable for the analysis.",
|
1318
1324
|
"target_height": "(int) - Target height for resizing the images.",
|
1319
1325
|
"target_intensity_min": "(float) - Minimum intensity for the target objects.",
|
@@ -1363,7 +1369,7 @@ def generate_fields(variables, scrollable_frame):
|
|
1363
1369
|
"masks": "(bool) - Whether to generate masks for the segmented objects.",
|
1364
1370
|
"timelapse": "(bool) - Whether to analyze images as a timelapse.",
|
1365
1371
|
"pathogen_min_size": "(int) - The minimum size of pathogen objects in pixels^2.",
|
1366
|
-
"pathogen_mask_dim": "(int) - The dimension of the array the pathogen mask is saved in.",
|
1372
|
+
"pathogen_mask_dim": "(int) - The dimension of the array the pathogen mask is saved in (array order:channels,cell, nucleus, pathogen, cytoplasm) array starts at dimension 0.",
|
1367
1373
|
"use_bounding_box": "(bool) - Whether to use the bounding box for cropping the images.",
|
1368
1374
|
"plot_points": "(bool) - Whether to plot scatterplot points.",
|
1369
1375
|
"embedding_by_controls": "(bool) - Use the controlls to greate the embedding, then apply this embedding to all of the data.",
|
@@ -1393,6 +1399,7 @@ def generate_fields(variables, scrollable_frame):
|
|
1393
1399
|
"shuffle": "(bool) - Shuffle the dataset bufore generating the activation maps",
|
1394
1400
|
"correlation": "(bool) - Calculate correlation between image channels and activation maps. Data is saved to .db.",
|
1395
1401
|
"normalize_input": "(bool) - Normalize the input images before passing them to the model.",
|
1402
|
+
"normalize_plots": "(bool) - Normalize images before plotting.",
|
1396
1403
|
}
|
1397
1404
|
|
1398
1405
|
for key, (var_type, options, default_value) in variables.items():
|
@@ -1444,8 +1451,8 @@ def set_annotate_default_settings(settings):
|
|
1444
1451
|
settings.setdefault('normalize', 'False')
|
1445
1452
|
settings.setdefault('normalize_channels', "r,g,b")
|
1446
1453
|
settings.setdefault('percentiles', [2, 98])
|
1447
|
-
settings.setdefault('measurement', '')#'cytoplasm_channel_3_mean_intensity,pathogen_channel_3_mean_intensity')
|
1448
|
-
settings.setdefault('threshold', '')#'2')
|
1454
|
+
settings.setdefault('measurement', '') #'cytoplasm_channel_3_mean_intensity,pathogen_channel_3_mean_intensity')
|
1455
|
+
settings.setdefault('threshold', '') #'2')
|
1449
1456
|
return settings
|
1450
1457
|
|
1451
1458
|
def set_default_generate_barecode_mapping(settings={}):
|
@@ -1465,6 +1472,7 @@ def set_default_generate_barecode_mapping(settings={}):
|
|
1465
1472
|
settings.setdefault('mode', 'paired')
|
1466
1473
|
settings.setdefault('single_direction', 'R1')
|
1467
1474
|
settings.setdefault('test', False)
|
1475
|
+
settings.setdefault('fill_na', False)
|
1468
1476
|
return settings
|
1469
1477
|
|
1470
1478
|
def get_default_generate_activation_map_settings(settings):
|