spacr 0.3.42__py3-none-any.whl → 0.3.45__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/cellpose.py +63 -73
- spacr/gui_core.py +5 -5
- spacr/gui_utils.py +1 -1
- spacr/io.py +76 -63
- spacr/ml.py +4 -3
- spacr/plot.py +265 -11
- spacr/settings.py +29 -8
- spacr/submodules.py +214 -10
- spacr/toxo.py +5 -116
- spacr/utils.py +103 -6
- {spacr-0.3.42.dist-info → spacr-0.3.45.dist-info}/METADATA +1 -1
- {spacr-0.3.42.dist-info → spacr-0.3.45.dist-info}/RECORD +16 -16
- {spacr-0.3.42.dist-info → spacr-0.3.45.dist-info}/LICENSE +0 -0
- {spacr-0.3.42.dist-info → spacr-0.3.45.dist-info}/WHEEL +0 -0
- {spacr-0.3.42.dist-info → spacr-0.3.45.dist-info}/entry_points.txt +0 -0
- {spacr-0.3.42.dist-info → spacr-0.3.45.dist-info}/top_level.txt +0 -0
spacr/plot.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
import os, random, cv2, glob, math, torch
|
1
|
+
import os, random, cv2, glob, math, torch, skimage
|
2
2
|
|
3
3
|
import numpy as np
|
4
4
|
import pandas as pd
|
5
5
|
import matplotlib.pyplot as plt
|
6
|
+
from matplotlib.colors import ListedColormap
|
6
7
|
import matplotlib as mpl
|
7
8
|
import scipy.ndimage as ndi
|
8
9
|
import seaborn as sns
|
@@ -13,6 +14,9 @@ from IPython.display import display
|
|
13
14
|
from skimage.segmentation import find_boundaries
|
14
15
|
from skimage import measure
|
15
16
|
from skimage.measure import find_contours, label, regionprops
|
17
|
+
from skimage.segmentation import mark_boundaries
|
18
|
+
from skimage.transform import resize as sk_resize
|
19
|
+
|
16
20
|
import tifffile as tiff
|
17
21
|
|
18
22
|
from scipy.stats import normaltest, ttest_ind, mannwhitneyu, f_oneway, kruskal
|
@@ -1520,8 +1524,135 @@ def plot_plates(df, variable, grouping, min_max, cmap, min_count=0, verbose=True
|
|
1520
1524
|
plt.show()
|
1521
1525
|
return fig
|
1522
1526
|
|
1523
|
-
def print_mask_and_flows(stack, mask, flows, overlay=
|
1524
|
-
|
1527
|
+
def print_mask_and_flows(stack, mask, flows, overlay=True, max_size=1000, thickness=2):
|
1528
|
+
"""
|
1529
|
+
Display the original image, mask with outlines, and flow images.
|
1530
|
+
|
1531
|
+
Args:
|
1532
|
+
stack (np.array): Original image or stack.
|
1533
|
+
mask (np.array): Mask image.
|
1534
|
+
flows (list): List of flow images.
|
1535
|
+
overlay (bool): Whether to overlay the mask outlines on the original image.
|
1536
|
+
max_size (int): Maximum allowed size for any dimension of the images.
|
1537
|
+
thickness (int): Thickness of the contour outlines.
|
1538
|
+
"""
|
1539
|
+
|
1540
|
+
def resize_if_needed(image, max_size):
|
1541
|
+
"""Resize image if any dimension exceeds max_size while maintaining aspect ratio."""
|
1542
|
+
if max(image.shape[:2]) > max_size:
|
1543
|
+
scale = max_size / max(image.shape[:2])
|
1544
|
+
new_shape = (int(image.shape[0] * scale), int(image.shape[1] * scale))
|
1545
|
+
if image.ndim == 3:
|
1546
|
+
new_shape += (image.shape[2],)
|
1547
|
+
return sk_resize(image, new_shape, preserve_range=True, anti_aliasing=True).astype(image.dtype)
|
1548
|
+
return image
|
1549
|
+
|
1550
|
+
def generate_contours(mask):
|
1551
|
+
"""Generate contours for each object in the mask using OpenCV."""
|
1552
|
+
contours, _ = cv2.findContours(mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
1553
|
+
return contours
|
1554
|
+
|
1555
|
+
def apply_contours_on_image(image, mask, color=(255, 0, 0), thickness=2):
|
1556
|
+
"""Draw the contours on the original image."""
|
1557
|
+
# Ensure the image is in RGB format
|
1558
|
+
if image.ndim == 2: # Grayscale to RGB
|
1559
|
+
image = normalize_to_uint8(image) # Convert to uint8 if needed
|
1560
|
+
image_rgb = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
|
1561
|
+
else:
|
1562
|
+
image_rgb = image.copy()
|
1563
|
+
|
1564
|
+
# Generate and draw contours
|
1565
|
+
contours = generate_contours(mask)
|
1566
|
+
cv2.drawContours(image_rgb, contours, -1, color, thickness)
|
1567
|
+
|
1568
|
+
return image_rgb
|
1569
|
+
|
1570
|
+
def normalize_to_uint8(image):
|
1571
|
+
"""Normalize and convert image to uint8."""
|
1572
|
+
image = np.clip(image, 0, 1) # Ensure values are between 0 and 1
|
1573
|
+
return (image * 255).astype(np.uint8) # Convert to uint8
|
1574
|
+
|
1575
|
+
|
1576
|
+
# Resize if necessary
|
1577
|
+
stack = resize_if_needed(stack, max_size)
|
1578
|
+
mask = resize_if_needed(mask, max_size)
|
1579
|
+
if flows != None:
|
1580
|
+
flows = [resize_if_needed(flow, max_size) for flow in flows]
|
1581
|
+
|
1582
|
+
fig, axs = plt.subplots(1, 3, figsize=(12, 4))
|
1583
|
+
else:
|
1584
|
+
fig, axs = plt.subplots(1, 2, figsize=(12, 4))
|
1585
|
+
|
1586
|
+
if stack.shape[-1] == 1:
|
1587
|
+
stack = np.squeeze(stack)
|
1588
|
+
|
1589
|
+
# Display original image
|
1590
|
+
if stack.ndim == 2:
|
1591
|
+
original_image = stack
|
1592
|
+
elif stack.ndim == 3:
|
1593
|
+
original_image = stack[..., 0] # Use the first channel as the base
|
1594
|
+
else:
|
1595
|
+
raise ValueError("Unexpected stack dimensionality.")
|
1596
|
+
|
1597
|
+
axs[0].imshow(original_image, cmap='gray')
|
1598
|
+
axs[0].set_title('Original Image')
|
1599
|
+
axs[0].axis('off')
|
1600
|
+
|
1601
|
+
# Overlay mask outlines on original image if overlay is True
|
1602
|
+
if overlay:
|
1603
|
+
outlined_image = apply_contours_on_image(original_image, mask, color=(255, 0, 0), thickness=thickness)
|
1604
|
+
axs[1].imshow(outlined_image)
|
1605
|
+
else:
|
1606
|
+
axs[1].imshow(mask, cmap='gray')
|
1607
|
+
|
1608
|
+
axs[1].set_title('Mask with Overlay' if overlay else 'Mask')
|
1609
|
+
axs[1].axis('off')
|
1610
|
+
|
1611
|
+
if flows != None:
|
1612
|
+
|
1613
|
+
# Display flow image or its first channel
|
1614
|
+
if flows and isinstance(flows, list) and flows[0].ndim in [2, 3]:
|
1615
|
+
flow_image = flows[0]
|
1616
|
+
if flow_image.ndim == 3:
|
1617
|
+
flow_image = flow_image[:, :, 0] # Use first channel for 3D
|
1618
|
+
axs[2].imshow(flow_image, cmap='jet')
|
1619
|
+
else:
|
1620
|
+
raise ValueError("Unexpected flow dimensionality or structure.")
|
1621
|
+
|
1622
|
+
axs[2].set_title('Flows')
|
1623
|
+
axs[2].axis('off')
|
1624
|
+
|
1625
|
+
fig.tight_layout()
|
1626
|
+
plt.show()
|
1627
|
+
|
1628
|
+
def print_mask_and_flows_v1(stack, mask, flows, overlay=False, max_size=1000):
|
1629
|
+
"""
|
1630
|
+
Display the original image, mask, and flow with optional resizing for large images.
|
1631
|
+
|
1632
|
+
Args:
|
1633
|
+
stack (np.array): Original image or stack.
|
1634
|
+
mask (np.array): Mask image.
|
1635
|
+
flows (list): List of flow images.
|
1636
|
+
overlay (bool): Whether to overlay the mask on the original image.
|
1637
|
+
max_size (int): Maximum allowed size for any dimension of the images.
|
1638
|
+
"""
|
1639
|
+
|
1640
|
+
def resize_if_needed(image, max_size):
|
1641
|
+
"""Resize image if any dimension exceeds max_size while maintaining aspect ratio."""
|
1642
|
+
if max(image.shape[:2]) > max_size:
|
1643
|
+
scale = max_size / max(image.shape[:2])
|
1644
|
+
new_shape = (int(image.shape[0] * scale), int(image.shape[1] * scale))
|
1645
|
+
if image.ndim == 3:
|
1646
|
+
new_shape += (image.shape[2],)
|
1647
|
+
return skimage.transform.resize(image, new_shape, preserve_range=True, anti_aliasing=True).astype(image.dtype)
|
1648
|
+
return image
|
1649
|
+
|
1650
|
+
# Resize if necessary
|
1651
|
+
stack = resize_if_needed(stack, max_size)
|
1652
|
+
mask = resize_if_needed(mask, max_size)
|
1653
|
+
flows = [resize_if_needed(flow, max_size) for flow in flows]
|
1654
|
+
|
1655
|
+
fig, axs = plt.subplots(1, 3, figsize=(12, 4)) # Adjust subplot layout
|
1525
1656
|
|
1526
1657
|
if stack.shape[-1] == 1:
|
1527
1658
|
stack = np.squeeze(stack)
|
@@ -2140,8 +2271,8 @@ def create_grouped_plot(df, grouping_column, data_column, graph_type='bar', summ
|
|
2140
2271
|
|
2141
2272
|
class spacrGraph:
|
2142
2273
|
def __init__(self, df, grouping_column, data_column, graph_type='bar', summary_func='mean',
|
2143
|
-
order=None, colors=None, output_dir='./output', save=False, y_lim=None,
|
2144
|
-
error_bar_type='std', remove_outliers=False, theme='pastel', representation='object',
|
2274
|
+
order=None, colors=None, output_dir='./output', save=False, y_lim=None, log_y=False,
|
2275
|
+
log_x=False, error_bar_type='std', remove_outliers=False, theme='pastel', representation='object',
|
2145
2276
|
paired=False, all_to_all=True, compare_group=None, graph_name=None):
|
2146
2277
|
|
2147
2278
|
"""
|
@@ -2166,7 +2297,8 @@ class spacrGraph:
|
|
2166
2297
|
self.compare_group = compare_group
|
2167
2298
|
self.y_lim = y_lim
|
2168
2299
|
self.graph_name = graph_name
|
2169
|
-
|
2300
|
+
self.log_x = log_x
|
2301
|
+
self.log_y = log_y
|
2170
2302
|
|
2171
2303
|
self.results_df = pd.DataFrame()
|
2172
2304
|
self.sns_palette = None
|
@@ -2582,6 +2714,11 @@ class spacrGraph:
|
|
2582
2714
|
# Set legend and labels
|
2583
2715
|
ax.set_xlabel(self.grouping_column)
|
2584
2716
|
|
2717
|
+
if self.log_y:
|
2718
|
+
ax.set_yscale('log')
|
2719
|
+
if self.log_x:
|
2720
|
+
ax.set_xscale('log')
|
2721
|
+
|
2585
2722
|
def _create_jitter_plot(self, ax):
|
2586
2723
|
"""Helper method to create a jitter plot (strip plot) with consistent spacing."""
|
2587
2724
|
# Combine grouping column and data column if needed
|
@@ -2606,6 +2743,11 @@ class spacrGraph:
|
|
2606
2743
|
unique_labels = dict(zip(labels, handles))
|
2607
2744
|
ax.legend(unique_labels.values(), unique_labels.keys(), loc='best')
|
2608
2745
|
|
2746
|
+
if self.log_y:
|
2747
|
+
ax.set_yscale('log')
|
2748
|
+
if self.log_x:
|
2749
|
+
ax.set_xscale('log')
|
2750
|
+
|
2609
2751
|
def _create_line_graph(self, ax):
|
2610
2752
|
"""Helper method to create a line graph with one line per group based on epochs and accuracy."""
|
2611
2753
|
#display(self.df)
|
@@ -2629,6 +2771,11 @@ class spacrGraph:
|
|
2629
2771
|
ax.set_xlabel(f"{x_axis_column}")
|
2630
2772
|
ax.set_ylabel(f"{y_axis_column}")
|
2631
2773
|
|
2774
|
+
if self.log_y:
|
2775
|
+
ax.set_yscale('log')
|
2776
|
+
if self.log_x:
|
2777
|
+
ax.set_xscale('log')
|
2778
|
+
|
2632
2779
|
def _create_line_with_std_area(self, ax):
|
2633
2780
|
"""Helper method to create a line graph with shaded area representing standard deviation."""
|
2634
2781
|
|
@@ -2652,7 +2799,12 @@ class spacrGraph:
|
|
2652
2799
|
# Adjust axis labels
|
2653
2800
|
ax.set_xlabel(f"{x_axis_column}")
|
2654
2801
|
ax.set_ylabel(f"{y_axis_column}")
|
2655
|
-
|
2802
|
+
|
2803
|
+
if self.log_y:
|
2804
|
+
ax.set_yscale('log')
|
2805
|
+
if self.log_x:
|
2806
|
+
ax.set_xscale('log')
|
2807
|
+
|
2656
2808
|
def _create_box_plot(self, ax):
|
2657
2809
|
"""Helper method to create a box plot with consistent spacing."""
|
2658
2810
|
# Combine grouping column and data column if needed
|
@@ -2676,6 +2828,11 @@ class spacrGraph:
|
|
2676
2828
|
handles, labels = ax.get_legend_handles_labels()
|
2677
2829
|
unique_labels = dict(zip(labels, handles))
|
2678
2830
|
ax.legend(unique_labels.values(), unique_labels.keys(), loc='best')
|
2831
|
+
|
2832
|
+
if self.log_y:
|
2833
|
+
ax.set_yscale('log')
|
2834
|
+
if self.log_x:
|
2835
|
+
ax.set_xscale('log')
|
2679
2836
|
|
2680
2837
|
def _create_violin_plot(self, ax):
|
2681
2838
|
"""Helper method to create a violin plot with consistent spacing."""
|
@@ -2702,6 +2859,11 @@ class spacrGraph:
|
|
2702
2859
|
unique_labels = dict(zip(labels, handles))
|
2703
2860
|
ax.legend(unique_labels.values(), unique_labels.keys(), loc='best')
|
2704
2861
|
|
2862
|
+
if self.log_y:
|
2863
|
+
ax.set_yscale('log')
|
2864
|
+
if self.log_x:
|
2865
|
+
ax.set_xscale('log')
|
2866
|
+
|
2705
2867
|
def _create_jitter_bar_plot(self, ax):
|
2706
2868
|
"""Helper method to create a bar plot with consistent bar thickness and centered error bars."""
|
2707
2869
|
# Flatten DataFrame: Combine grouping column and data column into one group if needed
|
@@ -2739,6 +2901,11 @@ class spacrGraph:
|
|
2739
2901
|
# Set legend and labels
|
2740
2902
|
ax.set_xlabel(self.grouping_column)
|
2741
2903
|
|
2904
|
+
if self.log_y:
|
2905
|
+
ax.set_yscale('log')
|
2906
|
+
if self.log_x:
|
2907
|
+
ax.set_xscale('log')
|
2908
|
+
|
2742
2909
|
def _create_jitter_box_plot(self, ax):
|
2743
2910
|
"""Helper method to create a box plot with consistent spacing."""
|
2744
2911
|
# Combine grouping column and data column if needed
|
@@ -2764,6 +2931,11 @@ class spacrGraph:
|
|
2764
2931
|
unique_labels = dict(zip(labels, handles))
|
2765
2932
|
ax.legend(unique_labels.values(), unique_labels.keys(), loc='best')
|
2766
2933
|
|
2934
|
+
if self.log_y:
|
2935
|
+
ax.set_yscale('log')
|
2936
|
+
if self.log_x:
|
2937
|
+
ax.set_xscale('log')
|
2938
|
+
|
2767
2939
|
def _save_results(self):
|
2768
2940
|
"""Helper method to save the plot and results."""
|
2769
2941
|
os.makedirs(self.output_dir, exist_ok=True)
|
@@ -2907,15 +3079,12 @@ def plot_data_from_csv(settings):
|
|
2907
3079
|
|
2908
3080
|
dfs = []
|
2909
3081
|
for i, src in enumerate(srcs):
|
2910
|
-
|
2911
3082
|
dft = pd.read_csv(src)
|
2912
3083
|
if 'plate' not in dft.columns:
|
2913
3084
|
dft['plate'] = f"plate{i+1}"
|
2914
3085
|
dfs.append(dft)
|
2915
|
-
|
2916
|
-
df = pd.concat(dfs, axis=0)
|
2917
|
-
#display(df)
|
2918
3086
|
|
3087
|
+
df = pd.concat(dfs, axis=0)
|
2919
3088
|
df = df.dropna(subset=settings['data_column'])
|
2920
3089
|
df = df.dropna(subset=settings['grouping_column'])
|
2921
3090
|
src = srcs[0]
|
@@ -2933,6 +3102,7 @@ def plot_data_from_csv(settings):
|
|
2933
3102
|
output_dir=dst, # Directory to save the plot and results
|
2934
3103
|
save=settings['save'], # Whether to save the plot and results
|
2935
3104
|
y_lim=settings['y_lim'], # Starting point for y-axis (optional)
|
3105
|
+
log_y=settings['log_y'], # Log-transform the y-axis
|
2936
3106
|
error_bar_type='std', # Type of error bar ('std' or 'sem')
|
2937
3107
|
representation=settings['representation'],
|
2938
3108
|
theme=settings['theme'], # Seaborn color palette theme (e.g., 'pastel', 'muted')
|
@@ -3073,3 +3243,87 @@ def plot_image_grid(image_paths, percentiles):
|
|
3073
3243
|
plt.subplots_adjust(wspace=0, hspace=0, left=0, right=1, top=1, bottom=0)
|
3074
3244
|
|
3075
3245
|
return fig
|
3246
|
+
|
3247
|
+
def overlay_masks_on_images(img_folder, normalize=True, resize=True, save=False, plot=False, thickness=2):
|
3248
|
+
"""
|
3249
|
+
Load images and masks from folders, overlay mask contours on images, and optionally normalize, resize, and save.
|
3250
|
+
|
3251
|
+
Args:
|
3252
|
+
img_folder (str): Path to the folder containing images.
|
3253
|
+
mask_folder (str): Path to the folder containing masks.
|
3254
|
+
normalize (bool): If True, normalize images to the 1st and 99th percentiles.
|
3255
|
+
resize (bool): If True, resize the final overlay to 500x500.
|
3256
|
+
save (bool): If True, save the final overlay in an 'overlay' folder within the image folder.
|
3257
|
+
thickness (int): Thickness of the contour lines.
|
3258
|
+
"""
|
3259
|
+
|
3260
|
+
def normalize_image(image):
|
3261
|
+
"""Normalize the image to the 1st and 99th percentiles."""
|
3262
|
+
lower, upper = np.percentile(image, [1, 99])
|
3263
|
+
image = np.clip((image - lower) / (upper - lower), 0, 1)
|
3264
|
+
return (image * 255).astype(np.uint8)
|
3265
|
+
|
3266
|
+
|
3267
|
+
mask_folder = os.path.join(img_folder,'masks')
|
3268
|
+
overlay_folder = os.path.join(img_folder, "overlay")
|
3269
|
+
if save and not os.path.exists(overlay_folder):
|
3270
|
+
os.makedirs(overlay_folder)
|
3271
|
+
|
3272
|
+
# Get common filenames in both image and mask folders
|
3273
|
+
image_filenames = set(os.listdir(img_folder))
|
3274
|
+
mask_filenames = set(os.listdir(mask_folder))
|
3275
|
+
common_filenames = image_filenames.intersection(mask_filenames)
|
3276
|
+
|
3277
|
+
if not common_filenames:
|
3278
|
+
print("No matching filenames found in both folders.")
|
3279
|
+
return
|
3280
|
+
|
3281
|
+
for filename in common_filenames:
|
3282
|
+
# Load image and mask
|
3283
|
+
img_path = os.path.join(img_folder, filename)
|
3284
|
+
mask_path = os.path.join(mask_folder, filename)
|
3285
|
+
|
3286
|
+
image = tiff.imread(img_path)
|
3287
|
+
mask = tiff.imread(mask_path)
|
3288
|
+
|
3289
|
+
# Normalize the image if requested
|
3290
|
+
if normalize:
|
3291
|
+
image = normalize_image(image)
|
3292
|
+
|
3293
|
+
# Ensure the mask is binary
|
3294
|
+
mask = (mask > 0).astype(np.uint8)
|
3295
|
+
|
3296
|
+
# Resize the mask if it doesn't match the image size
|
3297
|
+
if mask.shape != image.shape[:2]:
|
3298
|
+
mask = cv2.resize(mask, (image.shape[1], image.shape[0]), interpolation=cv2.INTER_NEAREST)
|
3299
|
+
|
3300
|
+
# Generate contours from the mask
|
3301
|
+
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
3302
|
+
|
3303
|
+
# Convert to RGB if grayscale
|
3304
|
+
if image.ndim == 2:
|
3305
|
+
image_rgb = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
|
3306
|
+
else:
|
3307
|
+
image_rgb = image.copy()
|
3308
|
+
|
3309
|
+
# Draw contours with alpha blending
|
3310
|
+
overlay = image_rgb.copy()
|
3311
|
+
cv2.drawContours(overlay, contours, -1, (255, 0, 0), thickness)
|
3312
|
+
blended = cv2.addWeighted(overlay, 0.7, image_rgb, 0.3, 0)
|
3313
|
+
|
3314
|
+
# Resize the final overlay if requested
|
3315
|
+
if resize:
|
3316
|
+
blended = cv2.resize(blended, (1000, 1000), interpolation=cv2.INTER_AREA)
|
3317
|
+
|
3318
|
+
# Save the overlay if requested
|
3319
|
+
if save:
|
3320
|
+
save_path = os.path.join(overlay_folder, filename)
|
3321
|
+
cv2.imwrite(save_path, cv2.cvtColor(blended, cv2.COLOR_RGB2BGR))
|
3322
|
+
|
3323
|
+
if plot:
|
3324
|
+
# Display the result
|
3325
|
+
plt.figure(figsize=(10, 10))
|
3326
|
+
plt.imshow(blended)
|
3327
|
+
plt.title(f"Overlay: {filename}")
|
3328
|
+
plt.axis('off')
|
3329
|
+
plt.show()
|
spacr/settings.py
CHANGED
@@ -566,7 +566,6 @@ def get_check_cellpose_models_default_settings(settings):
|
|
566
566
|
settings.setdefault('normalize', True)
|
567
567
|
settings.setdefault('channels', [0,0])
|
568
568
|
settings.setdefault('percentiles', None)
|
569
|
-
settings.setdefault('circular', False)
|
570
569
|
settings.setdefault('invert', False)
|
571
570
|
settings.setdefault('plot', True)
|
572
571
|
settings.setdefault('diameter', 40)
|
@@ -581,6 +580,7 @@ def get_check_cellpose_models_default_settings(settings):
|
|
581
580
|
return settings
|
582
581
|
|
583
582
|
def get_identify_masks_finetune_default_settings(settings):
|
583
|
+
settings.setdefault('src', 'path')
|
584
584
|
settings.setdefault('model_name', 'cyto')
|
585
585
|
settings.setdefault('custom_model', None)
|
586
586
|
settings.setdefault('channels', [0,0])
|
@@ -595,7 +595,6 @@ def get_identify_masks_finetune_default_settings(settings):
|
|
595
595
|
settings.setdefault('verbose', False)
|
596
596
|
settings.setdefault('normalize', True)
|
597
597
|
settings.setdefault('percentiles', None)
|
598
|
-
settings.setdefault('circular', False)
|
599
598
|
settings.setdefault('invert', False)
|
600
599
|
settings.setdefault('resize', False)
|
601
600
|
settings.setdefault('target_height', None)
|
@@ -603,6 +602,7 @@ def get_identify_masks_finetune_default_settings(settings):
|
|
603
602
|
settings.setdefault('rescale', False)
|
604
603
|
settings.setdefault('resample', False)
|
605
604
|
settings.setdefault('grayscale', True)
|
605
|
+
settings.setdefault('fill_in', True)
|
606
606
|
return settings
|
607
607
|
|
608
608
|
q = None
|
@@ -690,6 +690,7 @@ expected_types = {
|
|
690
690
|
"filter_min_max": (list, type(None)),
|
691
691
|
"channel_dims": list,
|
692
692
|
"backgrounds": list,
|
693
|
+
"background": str,
|
693
694
|
"outline_thickness": int,
|
694
695
|
"outline_color": str,
|
695
696
|
"overlay_chans": list,
|
@@ -706,6 +707,7 @@ expected_types = {
|
|
706
707
|
"remove_background_pathogen": bool,
|
707
708
|
"pathogen_model": (str, type(None)),
|
708
709
|
"filter": bool,
|
710
|
+
"fill_in":bool,
|
709
711
|
"upscale": bool,
|
710
712
|
"upscale_factor": float,
|
711
713
|
"adjust_cells": bool,
|
@@ -831,7 +833,6 @@ expected_types = {
|
|
831
833
|
"CP_prob": float,
|
832
834
|
"flow_threshold": float,
|
833
835
|
"percentiles": (list, type(None)),
|
834
|
-
"circular": bool,
|
835
836
|
"invert": bool,
|
836
837
|
"diameter": int,
|
837
838
|
"grayscale": bool,
|
@@ -897,7 +898,7 @@ expected_types = {
|
|
897
898
|
|
898
899
|
categories = {"Paths":[ "src", "grna", "barcodes", "custom_model_path", "dataset","model_path","grna_csv","row_csv","column_csv"],
|
899
900
|
"General": ["metadata_type", "custom_regex", "experiment", "channels", "magnification", "channel_dims", "apply_model_to_dataset", "generate_training_dataset", "train_DL_model", "segmentation_mode"],
|
900
|
-
"Cellpose":["from_scratch", "n_epochs", "width_height", "model_name", "custom_model", "resample", "rescale", "CP_prob", "flow_threshold", "percentiles", "
|
901
|
+
"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"],
|
901
902
|
"Cell": ["cell_intensity_range", "cell_size_range", "cell_chann_dim", "cell_channel", "cell_background", "cell_Signal_to_noise", "cell_CP_prob", "cell_FT", "remove_background_cell", "cell_min_size", "cell_mask_dim", "cytoplasm", "cytoplasm_min_size", "uninfected", "merge_edge_pathogen_cells", "adjust_cells", "cells", "cell_loc"],
|
902
903
|
"Nucleus": ["nucleus_intensity_range", "nucleus_size_range", "nucleus_chann_dim", "nucleus_channel", "nucleus_background", "nucleus_Signal_to_noise", "nucleus_CP_prob", "nucleus_FT", "remove_background_nucleus", "nucleus_min_size", "nucleus_mask_dim", "nucleus_loc"],
|
903
904
|
"Pathogen": ["pathogen_intensity_range", "pathogen_size_range", "pathogen_chann_dim", "pathogen_channel", "pathogen_background", "pathogen_Signal_to_noise", "pathogen_CP_prob", "pathogen_FT", "pathogen_model", "remove_background_pathogen", "pathogen_min_size", "pathogen_mask_dim", "pathogens", "pathogen_loc", "pathogen_types", "pathogen_plate_metadata", ],
|
@@ -909,12 +910,12 @@ categories = {"Paths":[ "src", "grna", "barcodes", "custom_model_path", "dataset
|
|
909
910
|
"Hyperparamiters (Embedding)": ["visualize","n_neighbors","min_dist","metric","resnet_features","reduction_method","embedding_by_controls","col_to_compare","log_data"],
|
910
911
|
"Hyperparamiters (Clustering)": ["eps","min_samples","analyze_clusters","clustering","remove_cluster_noise"],
|
911
912
|
"Hyperparamiters (Regression)":["cov_type", "class_1_threshold", "plate", "other", "fraction_threshold", "alpha", "random_row_column_effects", "regression_type", "min_cell_count", "agg_type", "transform", "dependent_variable"],
|
912
|
-
"Hyperparamiters (Activation)":["cam_type", "
|
913
|
+
"Hyperparamiters (Activation)":["cam_type", "overlay", "correlation", "target_layer", "normalize_input"],
|
913
914
|
"Annotation": ["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"],
|
914
915
|
"Plot": ["plot", "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"],
|
915
916
|
"Test": ["test_mode", "test_images", "random_test", "test_nr", "test", "test_split"],
|
916
917
|
"Timelapse": ["timelapse", "fps", "timelapse_displacement", "timelapse_memory", "timelapse_frame_limits", "timelapse_remove_transient", "timelapse_mode", "timelapse_objects", "compartments"],
|
917
|
-
"Advanced": ["shuffle", "target_intensity_min", "cells_per_well", "nuclei_limit", "pathogen_limit", "uninfected", "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"],
|
918
|
+
"Advanced": ["shuffle", "target_intensity_min", "cells_per_well", "nuclei_limit", "pathogen_limit", "uninfected", "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"],
|
918
919
|
"Miscellaneous": ["all_to_mip", "pick_slice", "skip_mode", "upscale", "upscale_factor"]
|
919
920
|
}
|
920
921
|
|
@@ -1069,6 +1070,7 @@ def generate_fields(variables, scrollable_frame):
|
|
1069
1070
|
"figuresize": "(tuple) - Size of the figures to plot.",
|
1070
1071
|
"filter": "(dict) - Filter settings for the analysis.",
|
1071
1072
|
"filter_by": "(str) - Feature to filter the data by.",
|
1073
|
+
"fill_in": "(bool) - Whether to fill in the segmented objects.",
|
1072
1074
|
"flow_threshold": "(float) - Flow threshold for segmentation.",
|
1073
1075
|
"fps": "(int) - Frames per second of the automatically generated timelapse movies.",
|
1074
1076
|
"fraction_threshold": "(float) - Threshold for the fraction of cells to consider in the analysis.",
|
@@ -1252,7 +1254,6 @@ def generate_fields(variables, scrollable_frame):
|
|
1252
1254
|
"pos": "(str) - Positive control identifier.",
|
1253
1255
|
"neg": "(str) - Negative control identifier.",
|
1254
1256
|
"minimum_cell_count": "(int) - Minimum number of cells/well. if number of cells < minimum_cell_count, the well is excluded from the analysis.",
|
1255
|
-
"circular": "(bool) - If a circle is to be drawn and corners excluded (e.g. square images of round wells).",
|
1256
1257
|
"highlight": "(str) - highlight genes/grnas containing this string.",
|
1257
1258
|
"pathogen_plate_metadata": "(str) - Metadata for the pathogen plate.",
|
1258
1259
|
"treatment_plate_metadata": "(str) - Metadata for the treatment plate.",
|
@@ -1313,6 +1314,8 @@ descriptions = {
|
|
1313
1314
|
|
1314
1315
|
'activation': "",
|
1315
1316
|
|
1317
|
+
'analyze_plaques': "Analyze plaque images to quantify plaque properties. Function: analyze_plaques from spacr.analysis.\n\nKey Features:\n- Plaque Analysis: Quantify plaque properties such as size, intensity, and shape.\n- Batch Processing: Analyze multiple plaque images efficiently.\n- Visualization: Generate visualizations to represent plaque data and patterns.",
|
1318
|
+
|
1316
1319
|
'recruitment': "Analyze recruitment data to understand sample recruitment dynamics. Function: recruitment_analysis_tools from spacr.analysis.\n\nKey Features:\n- Recruitment Analysis: Investigate and analyze the recruitment of samples over time or conditions.\n- Visualization: Generate visualizations to represent recruitment trends and patterns.\n- Integration: Utilize data from various sources for a comprehensive recruitment analysis."
|
1317
1320
|
}
|
1318
1321
|
|
@@ -1366,5 +1369,23 @@ def get_default_generate_activation_map_settings(settings):
|
|
1366
1369
|
settings.setdefault('correlation', True)
|
1367
1370
|
settings.setdefault('manders_thresholds', [15,50, 75])
|
1368
1371
|
settings.setdefault('n_jobs', None)
|
1369
|
-
|
1372
|
+
return settings
|
1373
|
+
|
1374
|
+
def get_analyze_plaque_settings(settings):
|
1375
|
+
settings.setdefault('src', 'path')
|
1376
|
+
settings.setdefault('masks', True)
|
1377
|
+
settings.setdefault('background', 200)
|
1378
|
+
settings.setdefault('Signal_to_noise', 10)
|
1379
|
+
settings.setdefault('CP_prob', 0)
|
1380
|
+
settings.setdefault('diameter', 30)
|
1381
|
+
settings.setdefault('batch_size', 50)
|
1382
|
+
settings.setdefault('flow_threshold', 0.4)
|
1383
|
+
settings.setdefault('save', True)
|
1384
|
+
settings.setdefault('verbose', True)
|
1385
|
+
settings.setdefault('resize', True)
|
1386
|
+
settings.setdefault('target_height', 1120)
|
1387
|
+
settings.setdefault('target_width', 1120)
|
1388
|
+
settings.setdefault('rescale', False)
|
1389
|
+
settings.setdefault('resample', False)
|
1390
|
+
settings.setdefault('fill_in', True)
|
1370
1391
|
return settings
|