spacr 0.2.4__py3-none-any.whl → 0.2.8__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/__init__.py +1 -11
- spacr/core.py +277 -349
- spacr/deep_spacr.py +248 -269
- spacr/gui.py +58 -54
- spacr/gui_core.py +689 -535
- spacr/gui_elements.py +1002 -153
- spacr/gui_utils.py +452 -107
- spacr/io.py +158 -91
- spacr/measure.py +199 -151
- spacr/plot.py +159 -47
- spacr/resources/font/open_sans/OFL.txt +93 -0
- spacr/resources/font/open_sans/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
- spacr/resources/font/open_sans/OpenSans-VariableFont_wdth,wght.ttf +0 -0
- spacr/resources/font/open_sans/README.txt +100 -0
- spacr/resources/font/open_sans/static/OpenSans-Bold.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans-BoldItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans-ExtraBold.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans-ExtraBoldItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans-Italic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans-Light.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans-LightItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans-Medium.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans-MediumItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans-Regular.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans-SemiBold.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans-SemiBoldItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_Condensed-Bold.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_Condensed-BoldItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBold.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBoldItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_Condensed-Italic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_Condensed-Light.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_Condensed-LightItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_Condensed-Medium.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_Condensed-MediumItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_Condensed-Regular.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBold.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBoldItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Bold.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-BoldItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBold.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBoldItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Italic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Light.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-LightItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Medium.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-MediumItalic.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Regular.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBold.ttf +0 -0
- spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBoldItalic.ttf +0 -0
- spacr/resources/icons/logo.pdf +2786 -6
- spacr/resources/icons/logo_spacr.png +0 -0
- spacr/resources/icons/logo_spacr_1.png +0 -0
- spacr/sequencing.py +477 -587
- spacr/settings.py +217 -144
- spacr/utils.py +46 -46
- {spacr-0.2.4.dist-info → spacr-0.2.8.dist-info}/METADATA +46 -35
- spacr-0.2.8.dist-info/RECORD +100 -0
- {spacr-0.2.4.dist-info → spacr-0.2.8.dist-info}/WHEEL +1 -1
- spacr-0.2.4.dist-info/RECORD +0 -58
- {spacr-0.2.4.dist-info → spacr-0.2.8.dist-info}/LICENSE +0 -0
- {spacr-0.2.4.dist-info → spacr-0.2.8.dist-info}/entry_points.txt +0 -0
- {spacr-0.2.4.dist-info → spacr-0.2.8.dist-info}/top_level.txt +0 -0
spacr/measure.py
CHANGED
@@ -13,6 +13,8 @@ from skimage.feature import graycomatrix, graycoprops
|
|
13
13
|
from mahotas.features import zernike_moments
|
14
14
|
from skimage import morphology, measure, filters
|
15
15
|
from skimage.util import img_as_bool
|
16
|
+
import matplotlib.pyplot as plt
|
17
|
+
from math import ceil, sqrt
|
16
18
|
|
17
19
|
from .logger import log_function_call
|
18
20
|
|
@@ -582,6 +584,113 @@ def _intensity_measurements(cell_mask, nucleus_mask, pathogen_mask, cytoplasm_ma
|
|
582
584
|
|
583
585
|
return pd.concat(cell_dfs, axis=1), pd.concat(nucleus_dfs, axis=1), pd.concat(pathogen_dfs, axis=1), pd.concat(cytoplasm_dfs, axis=1)
|
584
586
|
|
587
|
+
def save_and_add_image_to_grid(png_channels, img_path, grid, plot=False):
|
588
|
+
"""
|
589
|
+
Add an image to a grid and save it as PNG.
|
590
|
+
|
591
|
+
Args:
|
592
|
+
png_channels (ndarray): The array representing the image channels.
|
593
|
+
img_path (str): The path to save the image as PNG.
|
594
|
+
grid (list): The grid of images to be plotted later.
|
595
|
+
|
596
|
+
Returns:
|
597
|
+
grid (list): Updated grid with the new image added.
|
598
|
+
"""
|
599
|
+
|
600
|
+
# Save the image as a PNG
|
601
|
+
cv2.imwrite(img_path, png_channels)
|
602
|
+
|
603
|
+
if plot:
|
604
|
+
|
605
|
+
# Ensure the image is in uint8 format for cv2 functions
|
606
|
+
if png_channels.dtype == np.uint16:
|
607
|
+
png_channels = (png_channels / 256).astype(np.uint8)
|
608
|
+
|
609
|
+
# Get the filename without the extension
|
610
|
+
filename = os.path.splitext(os.path.basename(img_path))[0]
|
611
|
+
|
612
|
+
# Add the label to the image
|
613
|
+
#labeled_image = cv2.putText(png_channels.copy(), filename, (10, 30),
|
614
|
+
# cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)
|
615
|
+
|
616
|
+
# Add the labeled image to the grid
|
617
|
+
grid.append(png_channels)
|
618
|
+
|
619
|
+
return grid
|
620
|
+
|
621
|
+
def img_list_to_grid(grid, titles=None):
|
622
|
+
"""
|
623
|
+
Plot a grid of images with optional titles.
|
624
|
+
|
625
|
+
Args:
|
626
|
+
grid (list): List of images to be plotted.
|
627
|
+
titles (list): List of titles for the images.
|
628
|
+
|
629
|
+
Returns:
|
630
|
+
fig (Figure): The matplotlib figure object containing the image grid.
|
631
|
+
"""
|
632
|
+
n_images = len(grid)
|
633
|
+
grid_size = ceil(sqrt(n_images))
|
634
|
+
|
635
|
+
fig, axs = plt.subplots(grid_size, grid_size, figsize=(15, 15), facecolor='black')
|
636
|
+
|
637
|
+
for i, ax in enumerate(axs.flat):
|
638
|
+
if i < n_images:
|
639
|
+
image = grid[i]
|
640
|
+
ax.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
|
641
|
+
ax.axis('off')
|
642
|
+
ax.set_facecolor('black')
|
643
|
+
|
644
|
+
if titles:
|
645
|
+
# Determine text size
|
646
|
+
img_height, img_width = image.shape[:2]
|
647
|
+
text_size = max(min(img_width / (len(titles[i]) * 1.5), img_height / 10), 4)
|
648
|
+
ax.text(5, 5, titles[i], color='white', fontsize=text_size, ha='left', va='top', fontweight='bold')
|
649
|
+
else:
|
650
|
+
fig.delaxes(ax)
|
651
|
+
|
652
|
+
# Adjust spacing
|
653
|
+
plt.subplots_adjust(wspace=0.05, hspace=0.05)
|
654
|
+
plt.tight_layout(pad=0.1)
|
655
|
+
return fig
|
656
|
+
|
657
|
+
def filepaths_to_database(img_paths, settings, source_folder, crop_mode):
|
658
|
+
from. utils import _map_wells_png
|
659
|
+
png_df = pd.DataFrame(img_paths, columns=['png_path'])
|
660
|
+
|
661
|
+
png_df['file_name'] = png_df['png_path'].apply(lambda x: os.path.basename(x))
|
662
|
+
|
663
|
+
parts = png_df['file_name'].apply(lambda x: pd.Series(_map_wells_png(x, timelapse=settings['timelapse'])))
|
664
|
+
|
665
|
+
columns = ['plate', 'row', 'col', 'field']
|
666
|
+
|
667
|
+
if settings['timelapse']:
|
668
|
+
columns = columns + ['time_id']
|
669
|
+
|
670
|
+
columns = columns + ['prcfo']
|
671
|
+
|
672
|
+
if crop_mode == 'cell':
|
673
|
+
columns = columns + ['cell_id']
|
674
|
+
|
675
|
+
if crop_mode == 'nucleus':
|
676
|
+
columns = columns + ['nucleus_id']
|
677
|
+
|
678
|
+
if crop_mode == 'pathogen':
|
679
|
+
columns = columns + ['pathogen_id']
|
680
|
+
|
681
|
+
if crop_mode == 'cytoplasm':
|
682
|
+
columns = columns + ['cytoplasm_id']
|
683
|
+
|
684
|
+
png_df[columns] = parts
|
685
|
+
|
686
|
+
try:
|
687
|
+
conn = sqlite3.connect(f'{source_folder}/measurements/measurements.db', timeout=5)
|
688
|
+
png_df.to_sql('png_list', conn, if_exists='append', index=False)
|
689
|
+
conn.commit()
|
690
|
+
except sqlite3.OperationalError as e:
|
691
|
+
print(f"SQLite error: {e}", flush=True)
|
692
|
+
traceback.print_exc()
|
693
|
+
|
585
694
|
#@log_function_call
|
586
695
|
def _measure_crop_core(index, time_ls, file, settings):
|
587
696
|
|
@@ -603,20 +712,15 @@ def _measure_crop_core(index, time_ls, file, settings):
|
|
603
712
|
A list of cropped images.
|
604
713
|
"""
|
605
714
|
|
606
|
-
from .io import _create_database
|
607
715
|
from .plot import _plot_cropped_arrays
|
608
716
|
from .utils import _merge_overlapping_objects, _filter_object, _relabel_parent_with_child_labels, _exclude_objects, normalize_to_dtype
|
609
|
-
from .utils import _merge_and_save_to_database, _crop_center, _find_bounding_box, _generate_names, _get_percentiles
|
610
|
-
|
717
|
+
from .utils import _merge_and_save_to_database, _crop_center, _find_bounding_box, _generate_names, _get_percentiles
|
718
|
+
|
719
|
+
figs = {}
|
720
|
+
grid = []
|
611
721
|
start = time.time()
|
612
722
|
try:
|
613
723
|
source_folder = os.path.dirname(settings['src'])
|
614
|
-
#if not os.path.basename(source_folder).endswith('merged'):
|
615
|
-
# source_folder = os.path.join(source_folder, 'merged')
|
616
|
-
# print(f'changed source_folder to {source_folder}')
|
617
|
-
|
618
|
-
#if not os.path.exists(source_folder):
|
619
|
-
# return
|
620
724
|
|
621
725
|
file_name = os.path.splitext(file)[0]
|
622
726
|
data = np.load(os.path.join(settings['src'], file))
|
@@ -628,18 +732,13 @@ def _measure_crop_core(index, time_ls, file, settings):
|
|
628
732
|
if settings['verbose']:
|
629
733
|
print(f'Converted data from {data_type_before} to {data_type}')
|
630
734
|
|
631
|
-
if settings['
|
632
|
-
os.makedirs(source_folder+'/measurements', exist_ok=True)
|
633
|
-
_create_database(source_folder+'/measurements/measurements.db')
|
634
|
-
|
635
|
-
if settings['plot_filtration']:
|
636
|
-
|
735
|
+
if settings['plot']:
|
637
736
|
if len(data.shape) == 3:
|
638
737
|
figuresize = data.shape[2]*10
|
639
738
|
else:
|
640
739
|
figuresize = 10
|
641
|
-
|
642
|
-
|
740
|
+
fig = _plot_cropped_arrays(data, file, figuresize)
|
741
|
+
figs[f'{file_name}__before_filtration'] = fig
|
643
742
|
|
644
743
|
channel_arrays = data[:, :, settings['channels']].astype(data_type)
|
645
744
|
if settings['cell_mask_dim'] is not None:
|
@@ -714,9 +813,9 @@ def _measure_crop_core(index, time_ls, file, settings):
|
|
714
813
|
if settings['cytoplasm']:
|
715
814
|
data = np.concatenate((data, cytoplasm_mask[:, :, np.newaxis]), axis=2)
|
716
815
|
|
717
|
-
if settings['
|
718
|
-
_plot_cropped_arrays(data, file, figuresize)
|
719
|
-
|
816
|
+
if settings['plot']:
|
817
|
+
fig = _plot_cropped_arrays(data, file, figuresize)
|
818
|
+
figs[f'{file_name}__after_filtration'] = fig
|
720
819
|
|
721
820
|
if settings['save_measurements']:
|
722
821
|
|
@@ -837,53 +936,12 @@ def _measure_crop_core(index, time_ls, file, settings):
|
|
837
936
|
if png_channels.shape[2] == 2:
|
838
937
|
dummy_channel = np.zeros_like(png_channels[:,:,0]) # Create a 2D zero array with same shape as one channel
|
839
938
|
png_channels = np.dstack((png_channels, dummy_channel))
|
840
|
-
|
939
|
+
grid = save_and_add_image_to_grid(png_channels, img_path, grid, settings['plot'])
|
841
940
|
else:
|
842
|
-
|
941
|
+
grid = save_and_add_image_to_grid(png_channels, img_path, grid, settings['plot'])
|
843
942
|
|
844
943
|
if len(img_paths) == len(objects_in_image):
|
845
|
-
|
846
|
-
png_df = pd.DataFrame(img_paths, columns=['png_path'])
|
847
|
-
|
848
|
-
png_df['file_name'] = png_df['png_path'].apply(lambda x: os.path.basename(x))
|
849
|
-
|
850
|
-
parts = png_df['file_name'].apply(lambda x: pd.Series(_map_wells_png(x, timelapse=settings['timelapse'])))
|
851
|
-
|
852
|
-
columns = ['plate', 'row', 'col', 'field']
|
853
|
-
|
854
|
-
if settings['timelapse']:
|
855
|
-
columns = columns + ['time_id']
|
856
|
-
|
857
|
-
columns = columns + ['prcfo']
|
858
|
-
|
859
|
-
if crop_mode == 'cell':
|
860
|
-
columns = columns + ['cell_id']
|
861
|
-
|
862
|
-
if crop_mode == 'nucleus':
|
863
|
-
columns = columns + ['nucleus_id']
|
864
|
-
|
865
|
-
if crop_mode == 'pathogen':
|
866
|
-
columns = columns + ['pathogen_id']
|
867
|
-
|
868
|
-
if crop_mode == 'cytoplasm':
|
869
|
-
columns = columns + ['cytoplasm_id']
|
870
|
-
|
871
|
-
png_df[columns] = parts
|
872
|
-
|
873
|
-
try:
|
874
|
-
conn = sqlite3.connect(f'{source_folder}/measurements/measurements.db', timeout=5)
|
875
|
-
png_df.to_sql('png_list', conn, if_exists='append', index=False)
|
876
|
-
conn.commit()
|
877
|
-
except sqlite3.OperationalError as e:
|
878
|
-
print(f"SQLite error: {e}", flush=True)
|
879
|
-
traceback.print_exc()
|
880
|
-
|
881
|
-
if settings['plot']:
|
882
|
-
if len(png_channels.shape) == 3:
|
883
|
-
figuresize = png_channels.shape[2]*10
|
884
|
-
else:
|
885
|
-
figuresize = 10
|
886
|
-
_plot_cropped_arrays(png_channels, img_name, figuresize, threshold=1)
|
944
|
+
filepaths_to_database(img_paths, settings, source_folder, crop_mode)
|
887
945
|
|
888
946
|
if settings['save_arrays']:
|
889
947
|
row_idx, col_idx = np.where(region)
|
@@ -891,21 +949,12 @@ def _measure_crop_core(index, time_ls, file, settings):
|
|
891
949
|
array_folder = f"{fldr}/region_array/"
|
892
950
|
os.makedirs(array_folder, exist_ok=True)
|
893
951
|
np.save(os.path.join(array_folder, img_name), region_array)
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
if not settings['save_arrays'] and not settings['save_png'] and settings['plot']:
|
902
|
-
row_idx, col_idx = np.where(region)
|
903
|
-
region_array = data[row_idx.min():row_idx.max()+1, col_idx.min():col_idx.max()+1, :]
|
904
|
-
if len(png_channels.shape) == 3:
|
905
|
-
figuresize = png_channels.shape[2]*10
|
906
|
-
else:
|
907
|
-
figuresize = 10
|
908
|
-
_plot_cropped_arrays(png_channels, file, figuresize, threshold=1)
|
952
|
+
|
953
|
+
grid = save_and_add_image_to_grid(png_channels, img_path, grid, settings['plot'])
|
954
|
+
|
955
|
+
img_paths.append(img_path)
|
956
|
+
if len(img_paths) == len(objects_in_image):
|
957
|
+
filepaths_to_database(img_paths, settings, source_folder, crop_mode)
|
909
958
|
|
910
959
|
cells = np.unique(cell_mask)
|
911
960
|
except Exception as e:
|
@@ -917,7 +966,10 @@ def _measure_crop_core(index, time_ls, file, settings):
|
|
917
966
|
duration = end-start
|
918
967
|
time_ls.append(duration)
|
919
968
|
average_time = np.mean(time_ls) if len(time_ls) > 0 else 0
|
920
|
-
|
969
|
+
if settings['plot']:
|
970
|
+
fig = img_list_to_grid(grid)
|
971
|
+
figs[f'{file_name}__pngs'] = fig
|
972
|
+
return index, average_time, cells, figs
|
921
973
|
|
922
974
|
#@log_function_call
|
923
975
|
def measure_crop(settings):
|
@@ -932,23 +984,24 @@ def measure_crop(settings):
|
|
932
984
|
None
|
933
985
|
"""
|
934
986
|
|
935
|
-
from .io import _save_settings_to_db
|
936
|
-
from .timelapse import _timelapse_masks_to_gif
|
937
|
-
from .
|
938
|
-
from .utils import _list_endpoint_subdirectories, _generate_representative_images, measure_test_mode, print_progress
|
987
|
+
from .io import _save_settings_to_db, _create_database
|
988
|
+
from .timelapse import _timelapse_masks_to_gif
|
989
|
+
from .utils import measure_test_mode, print_progress
|
939
990
|
from .settings import get_measure_crop_settings
|
940
991
|
|
941
992
|
settings = get_measure_crop_settings(settings)
|
942
993
|
settings = measure_test_mode(settings)
|
943
994
|
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
995
|
+
src_fldr = settings['src']
|
996
|
+
if not os.path.basename(src_fldr).endswith('merged'):
|
997
|
+
print(f"WARNING: Source folder, settings: src: {src_fldr} should end with '/merged'")
|
998
|
+
src_fldr = os.path.join(src_fldr, 'merged')
|
999
|
+
print(f"Changed source folder to: {src_fldr}")
|
948
1000
|
|
949
|
-
|
950
|
-
|
951
|
-
|
1001
|
+
if settings['save_measurements']:
|
1002
|
+
source_folder = os.path.dirname(settings['src'])
|
1003
|
+
os.makedirs(source_folder+'/measurements', exist_ok=True)
|
1004
|
+
_create_database(source_folder+'/measurements/measurements.db')
|
952
1005
|
|
953
1006
|
if settings['cell_mask_dim'] is None:
|
954
1007
|
settings['include_uninfected'] = True
|
@@ -960,7 +1013,15 @@ def measure_crop(settings):
|
|
960
1013
|
settings['cytoplasm'] = True
|
961
1014
|
else:
|
962
1015
|
settings['cytoplasm'] = False
|
963
|
-
|
1016
|
+
|
1017
|
+
spacr_cores = int(mp.cpu_count() - 6)
|
1018
|
+
if spacr_cores <= 2:
|
1019
|
+
spacr_cores = 1
|
1020
|
+
|
1021
|
+
if settings['n_jobs'] > spacr_cores:
|
1022
|
+
print(f'Warning reserving 6 CPU cores for other processes, setting n_jobs to {spacr_cores}')
|
1023
|
+
settings['n_jobs'] = spacr_cores
|
1024
|
+
|
964
1025
|
dirname = os.path.dirname(settings['src'])
|
965
1026
|
settings_df = pd.DataFrame(list(settings.items()), columns=['Key', 'Value'])
|
966
1027
|
settings_csv = os.path.join(dirname,'settings','measure_crop_settings.csv')
|
@@ -997,76 +1058,63 @@ def measure_crop(settings):
|
|
997
1058
|
|
998
1059
|
_save_settings_to_db(settings)
|
999
1060
|
files = [f for f in os.listdir(settings['src']) if f.endswith('.npy')]
|
1000
|
-
n_jobs = settings['n_jobs']
|
1061
|
+
n_jobs = settings['n_jobs']
|
1001
1062
|
print(f'using {n_jobs} cpu cores')
|
1063
|
+
print_progress(files_processed=0, files_to_process=len(files), n_jobs=n_jobs, time_ls=[], operation_type='Measure and Crop')
|
1064
|
+
|
1065
|
+
def job_callback(result):
|
1066
|
+
completed_jobs.add(result[0])
|
1067
|
+
process_meassure_crop_results([result], settings)
|
1068
|
+
files_processed = len(completed_jobs)
|
1069
|
+
files_to_process = len(files)
|
1070
|
+
print_progress(files_processed, files_to_process, n_jobs, time_ls=time_ls, operation_type='Measure and Crop')
|
1071
|
+
if files_processed >= files_to_process:
|
1072
|
+
pool.terminate()
|
1073
|
+
|
1002
1074
|
with mp.Manager() as manager:
|
1003
1075
|
time_ls = manager.list()
|
1076
|
+
completed_jobs = set() # Set to keep track of completed jobs
|
1077
|
+
|
1004
1078
|
with mp.Pool(n_jobs) as pool:
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
files_processed = len(time_ls)
|
1011
|
-
files_to_process = len(files)
|
1012
|
-
print_progress(files_processed, files_to_process, n_jobs, time_ls=None)
|
1013
|
-
result.get()
|
1014
|
-
|
1015
|
-
if settings['representative_images']:
|
1016
|
-
if settings['save_png']:
|
1017
|
-
img_fldr = os.path.join(os.path.dirname(settings['src']), 'data')
|
1018
|
-
sc_img_fldrs = _list_endpoint_subdirectories(img_fldr)
|
1019
|
-
|
1020
|
-
for i, well_src in enumerate(sc_img_fldrs):
|
1021
|
-
if len(os.listdir(well_src)) < 16:
|
1022
|
-
nr_imgs = len(os.listdir(well_src))
|
1023
|
-
standardize = False
|
1024
|
-
else:
|
1025
|
-
nr_imgs = 16
|
1026
|
-
standardize = True
|
1027
|
-
try:
|
1028
|
-
all_folders = len(sc_img_fldrs)
|
1029
|
-
_save_scimg_plot(src=well_src, nr_imgs=nr_imgs, channel_indices=settings['png_dims'], um_per_pixel=0.1, scale_bar_length_um=10, standardize=standardize, fontsize=12, show_filename=True, channel_names=['red','green','blue'], dpi=300, plot=False, i=i, all_folders=all_folders)
|
1030
|
-
|
1031
|
-
except Exception as e:
|
1032
|
-
print(f"Unable to generate figure for folder {well_src}: {e}", end='\r', flush=True)
|
1033
|
-
#traceback.print_exc()
|
1034
|
-
|
1035
|
-
if settings['save_measurements']:
|
1036
|
-
db_path = os.path.join(os.path.dirname(settings['src']), 'measurements', 'measurements.db')
|
1037
|
-
channel_indices = settings['png_dims']
|
1038
|
-
channel_indices = [min(value, 2) for value in channel_indices]
|
1039
|
-
_generate_representative_images(db_path,
|
1040
|
-
cells=settings['cells'],
|
1041
|
-
cell_loc=settings['cell_loc'],
|
1042
|
-
pathogens=settings['pathogens'],
|
1043
|
-
pathogen_loc=settings['pathogen_loc'],
|
1044
|
-
treatments=settings['treatments'],
|
1045
|
-
treatment_loc=settings['treatment_loc'],
|
1046
|
-
channel_of_interest=settings['channel_of_interest'],
|
1047
|
-
compartments = settings['compartments'],
|
1048
|
-
measurement = settings['measurement'],
|
1049
|
-
nr_imgs=settings['nr_imgs'],
|
1050
|
-
channel_indices=channel_indices,
|
1051
|
-
um_per_pixel=settings['um_per_pixel'],
|
1052
|
-
scale_bar_length_um=10,
|
1053
|
-
plot=False,
|
1054
|
-
fontsize=12,
|
1055
|
-
show_filename=True,
|
1056
|
-
channel_names=None)
|
1079
|
+
for index, file in enumerate(files):
|
1080
|
+
pool.apply_async(_measure_crop_core, args=(index, time_ls, file, settings), callback=job_callback)
|
1081
|
+
|
1082
|
+
pool.close()
|
1083
|
+
pool.join()
|
1057
1084
|
|
1058
1085
|
if settings['timelapse']:
|
1059
1086
|
if settings['timelapse_objects'] == 'nucleus':
|
1060
1087
|
folder_path = settings['src']
|
1061
|
-
mask_channels = [settings['nucleus_mask_dim'], settings['pathogen_mask_dim'],settings['cell_mask_dim']]
|
1062
|
-
object_types = ['nucleus','pathogen','cell']
|
1088
|
+
mask_channels = [settings['nucleus_mask_dim'], settings['pathogen_mask_dim'], settings['cell_mask_dim']]
|
1089
|
+
object_types = ['nucleus', 'pathogen', 'cell']
|
1063
1090
|
_timelapse_masks_to_gif(folder_path, mask_channels, object_types)
|
1064
1091
|
|
1065
|
-
#if settings['save_png']:
|
1066
|
-
img_fldr = os.path.join(os.path.dirname(settings['src']), 'data')
|
1067
|
-
sc_img_fldrs = _list_endpoint_subdirectories(img_fldr)
|
1068
|
-
_scmovie(sc_img_fldrs)
|
1069
1092
|
print("Successfully completed run")
|
1093
|
+
|
1094
|
+
def process_meassure_crop_results(partial_results, settings):
|
1095
|
+
"""
|
1096
|
+
Process the results, display, and optionally save the figures.
|
1097
|
+
|
1098
|
+
Args:
|
1099
|
+
partial_results (list): List of partial results.
|
1100
|
+
settings (dict): Settings dictionary.
|
1101
|
+
save_figures (bool): Flag to save figures or not.
|
1102
|
+
"""
|
1103
|
+
for result in partial_results:
|
1104
|
+
if result is None:
|
1105
|
+
continue
|
1106
|
+
index, avg_time, cells, figs = result
|
1107
|
+
if figs is not None:
|
1108
|
+
for key, fig in figs.items():
|
1109
|
+
part_1, part_2 = key.split('__')
|
1110
|
+
save_dir = os.path.join(os.path.dirname(settings['src']), 'results', f"{part_1}")
|
1111
|
+
os.makedirs(save_dir, exist_ok=True)
|
1112
|
+
fig_path = os.path.join(save_dir, f"{part_2}.pdf")
|
1113
|
+
fig.savefig(fig_path)
|
1114
|
+
plt.figure(fig.number)
|
1115
|
+
plt.show()
|
1116
|
+
plt.close(fig)
|
1117
|
+
result = (index, None, None, None)
|
1070
1118
|
|
1071
1119
|
def generate_cellpose_train_set(folders, dst, min_objects=5):
|
1072
1120
|
os.makedirs(dst, exist_ok=True)
|