From 42611cea6a4cd4193a48475a258a8c36bf57b278 Mon Sep 17 00:00:00 2001
From: polarbean <harry.carey95@gmail.com>
Date: Tue, 25 Mar 2025 20:38:52 +0100
Subject: [PATCH] black format
---
PyNutil/io/atlas_loader.py | 2 +-
PyNutil/io/file_operations.py | 19 +-
PyNutil/io/read_and_write.py | 14 +-
PyNutil/main.py | 9 +-
PyNutil/processing/coordinate_extraction.py | 15 +-
PyNutil/processing/counting_and_load.py | 197 ++++++++++++++------
PyNutil/processing/data_analysis.py | 119 ++++++++----
PyNutil/processing/utils.py | 20 +-
gui/PyNutilGUI.py | 8 +-
tests/test_quantification.py | 7 +-
10 files changed, 281 insertions(+), 129 deletions(-)
diff --git a/PyNutil/io/atlas_loader.py b/PyNutil/io/atlas_loader.py
index 21ac5d2..0a58f18 100644
--- a/PyNutil/io/atlas_loader.py
+++ b/PyNutil/io/atlas_loader.py
@@ -40,7 +40,7 @@ def load_atlas_data(atlas_name):
atlas_volume = process_atlas_volume(atlas.annotation)
hemi_map = process_atlas_volume(atlas.hemispheres)
print("atlas labels loaded ✅")
- return atlas_volume,hemi_map, atlas_labels
+ return atlas_volume, hemi_map, atlas_labels
def process_atlas_volume(vol):
diff --git a/PyNutil/io/file_operations.py b/PyNutil/io/file_operations.py
index 5c02874..3d67649 100644
--- a/PyNutil/io/file_operations.py
+++ b/PyNutil/io/file_operations.py
@@ -105,7 +105,6 @@ def save_analysis_output(
"alignment_json": alignment_json,
"colour": colour,
"custom_region_path": custom_region_path,
-
}
pixel_points,
centroids,
@@ -120,15 +119,15 @@ def save_analysis_output(
segmentation_filenames,
atlas_labels,
output_folder,
- segmentation_folder=None,
- alignment_json=None,
- colour=None,
- atlas_name=None,
- custom_region_path=None,
- atlas_path=None,
- label_path=None,
- settings_file=None,
- prepend=None,
+ segmentation_folder = (None,)
+ alignment_json = (None,)
+ colour = (None,)
+ atlas_name = (None,)
+ custom_region_path = (None,)
+ atlas_path = (None,)
+ label_path = (None,)
+ settings_file = (None,)
+ prepend = (None,)
# Add atlas information to settings
if atlas_name:
settings_dict["atlas_name"] = atlas_name
diff --git a/PyNutil/io/read_and_write.py b/PyNutil/io/read_and_write.py
index c33ab17..8113b62 100644
--- a/PyNutil/io/read_and_write.py
+++ b/PyNutil/io/read_and_write.py
@@ -307,17 +307,19 @@ def write_points_to_meshview(points, point_names, hemi_label, filename, info_fil
A table with region IDs, names, and color data (r, g, b) for each region.
"""
if not (hemi_label == None).all():
- split_fn_left = filename.split('/')
+ split_fn_left = filename.split("/")
split_fn_left[-1] = "left_hemisphere_" + split_fn_left[-1]
outname_left = os.sep.join(split_fn_left)
- left_region_dict = create_region_dict(points[hemi_label==1], point_names[hemi_label==1])
+ left_region_dict = create_region_dict(
+ points[hemi_label == 1], point_names[hemi_label == 1]
+ )
write_points(left_region_dict, outname_left, info_file)
- split_fn_right = filename.split('/')
+ split_fn_right = filename.split("/")
split_fn_right[-1] = "right_hemisphere_" + split_fn_right[-1]
outname_right = os.sep.join(split_fn_right)
- right_region_dict = create_region_dict(points[hemi_label==2], point_names[hemi_label==2])
+ right_region_dict = create_region_dict(
+ points[hemi_label == 2], point_names[hemi_label == 2]
+ )
write_points(right_region_dict, outname_right, info_file)
region_dict = create_region_dict(points, point_names)
write_points(region_dict, filename, info_file)
-
-
diff --git a/PyNutil/main.py b/PyNutil/main.py
index 4bee193..72d65e3 100644
--- a/PyNutil/main.py
+++ b/PyNutil/main.py
@@ -9,6 +9,7 @@ from .io.file_operations import save_analysis_output
from .io.read_and_write import open_custom_region_file
from .processing.coordinate_extraction import folder_to_atlas_space
+
class PyNutil:
"""
A class to perform brain-wide quantification and spatial analysis of serial section images.
@@ -130,7 +131,9 @@ class PyNutil:
"When atlas_path and label_path are not specified, atlas_name must be specified."
)
- def get_coordinates(self, non_linear=True, object_cutoff=0, use_flat=False, apply_damage_mask=True):
+ def get_coordinates(
+ self, non_linear=True, object_cutoff=0, use_flat=False, apply_damage_mask=True
+ ):
"""
Retrieves pixel and centroid coordinates from segmentation data,
applies atlas-space transformations, and optionally uses a damage
@@ -169,7 +172,7 @@ class PyNutil:
self.atlas_volume,
self.hemi_map,
use_flat,
- apply_damage_mask
+ apply_damage_mask,
)
self.apply_damage_mask = apply_damage_mask
if self.custom_regions_dict is not None:
@@ -219,7 +222,7 @@ class PyNutil:
self.centroids_hemi_labels,
self.per_point_undamaged,
self.per_centroid_undamaged,
- self.apply_damage_mask
+ self.apply_damage_mask,
)
if self.custom_regions_dict is not None:
self.custom_label_df, self.label_df = apply_custom_regions(
diff --git a/PyNutil/processing/coordinate_extraction.py b/PyNutil/processing/coordinate_extraction.py
index 6a44490..dd4bbeb 100644
--- a/PyNutil/processing/coordinate_extraction.py
+++ b/PyNutil/processing/coordinate_extraction.py
@@ -114,7 +114,7 @@ def folder_to_atlas_space(
atlas_volume=None,
hemi_map=None,
use_flat=False,
- apply_damage_mask=True
+ apply_damage_mask=True,
):
"""
Processes all segmentation files in a folder, mapping each one to atlas space.
@@ -221,7 +221,6 @@ def folder_to_atlas_space(
)
-
def create_threads(
segmentations,
slices,
@@ -389,7 +388,9 @@ def get_region_areas(
(seg_width, seg_height),
atlas_labels,
)
- region_areas = flat_to_dataframe(atlas_map, damage_mask, hemi_mask, (seg_width, seg_height))
+ region_areas = flat_to_dataframe(
+ atlas_map, damage_mask, hemi_mask, (seg_width, seg_height)
+ )
return region_areas, atlas_map
@@ -473,7 +474,7 @@ def segmentation_to_atlas_space(
)
atlas_map = rescale_image(atlas_map, (reg_height, reg_width))
y_scale, x_scale = transform_to_registration(
- seg_width, seg_height, reg_width,reg_height
+ seg_width, seg_height, reg_width, reg_height
)
centroids, points = None, None
scaled_centroidsX, scaled_centroidsY, scaled_x, scaled_y = None, None, None, None
@@ -524,7 +525,6 @@ def segmentation_to_atlas_space(
per_point_hemi = [None] * len(scaled_x)
per_centroid_hemi = [None] * len(scaled_centroidsX)
-
per_point_labels = per_point_labels[per_point_undamaged]
per_centroid_labels = per_centroid_labels[per_centroid_undamaged]
@@ -560,7 +560,10 @@ def segmentation_to_atlas_space(
per_point_undamaged if points is not None else []
)
points_hemi_labels[index] = np.array(per_point_hemi if points is not None else [])
- centroids_hemi_labels[index] = np.array(per_centroid_hemi if points is not None else [])
+ centroids_hemi_labels[index] = np.array(
+ per_centroid_hemi if points is not None else []
+ )
+
def get_triangulation(slice_dict, reg_width, reg_height, non_linear):
"""
diff --git a/PyNutil/processing/counting_and_load.py b/PyNutil/processing/counting_and_load.py
index e7b7107..6914bc4 100644
--- a/PyNutil/processing/counting_and_load.py
+++ b/PyNutil/processing/counting_and_load.py
@@ -5,6 +5,7 @@ import cv2
from .generate_target_slice import generate_target_slice
from .visualign_deformations import transform_vec
+
def create_base_counts_dict(with_hemisphere=False, with_damage=False):
"""
Creates and returns a base dictionary structure for tracking counts.
@@ -30,8 +31,8 @@ def create_base_counts_dict(with_hemisphere=False, with_damage=False):
"undamaged_object_count": [],
"damaged_object_count": [],
"undamaged_pixel_count": [],
- "damaged_pixel_counts": []
- }
+ "damaged_pixel_counts": [],
+ }
counts.update(damage_fields)
if with_hemisphere:
hemisphere_fields = {
@@ -39,7 +40,7 @@ def create_base_counts_dict(with_hemisphere=False, with_damage=False):
"right_hemi_pixel_count": [],
"left_hemi_object_count": [],
"right_hemi_object_count": [],
- }
+ }
counts.update(hemisphere_fields)
if with_damage and with_hemisphere:
damage_hemisphere_fields = {
@@ -51,10 +52,11 @@ def create_base_counts_dict(with_hemisphere=False, with_damage=False):
"left_hemi_damaged_object_count": [],
"right_hemi_undamaged_object_count": [],
"right_hemi_damaged_object_count": [],
- }
+ }
counts.update(damage_hemisphere_fields)
return counts
+
# related to counting_and_load
def pixel_count_per_region(
labels_dict_points,
@@ -64,7 +66,7 @@ def pixel_count_per_region(
current_points_hemi,
current_centroids_hemi,
df_label_colours,
- with_damage=False
+ with_damage=False,
):
"""
Tally object counts by region, optionally tracking damage and hemispheres.
@@ -83,33 +85,75 @@ def pixel_count_per_region(
DataFrame: Summed counts per region.
"""
with_hemi = None not in current_points_hemi
- counts_per_label = create_base_counts_dict(with_hemisphere=with_hemi, with_damage=with_damage)
+ counts_per_label = create_base_counts_dict(
+ with_hemisphere=with_hemi, with_damage=with_damage
+ )
if with_hemi and with_damage:
- left_hemi_counted_labels_points_undamaged, left_hemi_label_counts_points_undamaged = np.unique(
- labels_dict_points[current_points_undamaged & (current_points_hemi == 1)], return_counts=True
- )
- left_hemi_counted_labels_points_damaged, left_hemi_label_counts_points_damaged = np.unique(
- labels_dict_points[~current_points_undamaged & (current_points_hemi == 1)], return_counts=True
- )
- left_hemi_counted_labels_centroids_undamaged, left_hemi_label_counts_centroids_undamaged = np.unique(
- labeled_dict_centroids[current_centroids_undamaged & (current_centroids_hemi == 1)], return_counts=True
- )
- left_hemi_counted_labels_centroids_damaged, left_hemi_label_counts_centroids_damaged = np.unique(
- labeled_dict_centroids[~current_centroids_undamaged & (current_centroids_hemi == 1)], return_counts=True
- )
- right_hemi_counted_labels_points_undamaged, right_hemi_label_counts_points_undamaged = np.unique(
- labels_dict_points[current_points_undamaged & (current_points_hemi == 2)], return_counts=True
- )
- right_hemi_counted_labels_points_damaged, right_hemi_label_counts_points_damaged = np.unique(
- labels_dict_points[~current_points_undamaged & (current_points_hemi == 2)], return_counts=True
- )
- right_hemi_counted_labels_centroids_undamaged, right_hemi_label_counts_centroids_undamaged = np.unique(
- labeled_dict_centroids[current_centroids_undamaged & (current_centroids_hemi == 2)], return_counts=True
- )
- right_hemi_counted_labels_centroids_damaged, right_hemi_label_counts_centroids_damaged = np.unique(
- labeled_dict_centroids[~current_centroids_undamaged & (current_centroids_hemi == 2)], return_counts=True
- )
+ (
+ left_hemi_counted_labels_points_undamaged,
+ left_hemi_label_counts_points_undamaged,
+ ) = np.unique(
+ labels_dict_points[current_points_undamaged & (current_points_hemi == 1)],
+ return_counts=True,
+ )
+ (
+ left_hemi_counted_labels_points_damaged,
+ left_hemi_label_counts_points_damaged,
+ ) = np.unique(
+ labels_dict_points[~current_points_undamaged & (current_points_hemi == 1)],
+ return_counts=True,
+ )
+ (
+ left_hemi_counted_labels_centroids_undamaged,
+ left_hemi_label_counts_centroids_undamaged,
+ ) = np.unique(
+ labeled_dict_centroids[
+ current_centroids_undamaged & (current_centroids_hemi == 1)
+ ],
+ return_counts=True,
+ )
+ (
+ left_hemi_counted_labels_centroids_damaged,
+ left_hemi_label_counts_centroids_damaged,
+ ) = np.unique(
+ labeled_dict_centroids[
+ ~current_centroids_undamaged & (current_centroids_hemi == 1)
+ ],
+ return_counts=True,
+ )
+ (
+ right_hemi_counted_labels_points_undamaged,
+ right_hemi_label_counts_points_undamaged,
+ ) = np.unique(
+ labels_dict_points[current_points_undamaged & (current_points_hemi == 2)],
+ return_counts=True,
+ )
+ (
+ right_hemi_counted_labels_points_damaged,
+ right_hemi_label_counts_points_damaged,
+ ) = np.unique(
+ labels_dict_points[~current_points_undamaged & (current_points_hemi == 2)],
+ return_counts=True,
+ )
+ (
+ right_hemi_counted_labels_centroids_undamaged,
+ right_hemi_label_counts_centroids_undamaged,
+ ) = np.unique(
+ labeled_dict_centroids[
+ current_centroids_undamaged & (current_centroids_hemi == 2)
+ ],
+ return_counts=True,
+ )
+ (
+ right_hemi_counted_labels_centroids_damaged,
+ right_hemi_label_counts_centroids_damaged,
+ ) = np.unique(
+ labeled_dict_centroids[
+ ~current_centroids_undamaged & (current_centroids_hemi == 2)
+ ],
+ return_counts=True,
+ )
for index, row in df_label_colours.iterrows():
# Left hemisphere pixel counts
if row["idx"] in left_hemi_counted_labels_points_undamaged:
@@ -172,7 +216,17 @@ def pixel_count_per_region(
r_clcd = 0
# Skip regions with no counts in any category
- if l_clcd == l_clcu == l_clpd == l_clpu == r_clcd == r_clcu == r_clpd == r_clpu == 0:
+ if (
+ l_clcd
+ == l_clcu
+ == l_clpd
+ == l_clpu
+ == r_clcd
+ == r_clcu
+ == r_clpd
+ == r_clpu
+ == 0
+ ):
continue
# Calculate combined counts
@@ -214,17 +268,19 @@ def pixel_count_per_region(
elif with_damage and (not with_hemi):
counted_labels_points_undamaged, label_counts_points_undamaged = np.unique(
- labels_dict_points[current_points_undamaged], return_counts=True
- )
+ labels_dict_points[current_points_undamaged], return_counts=True
+ )
counted_labels_points_damaged, label_counts_points_damaged = np.unique(
labels_dict_points[~current_points_undamaged], return_counts=True
+ )
+ counted_labels_centroids_undamaged, label_counts_centroids_undamaged = (
+ np.unique(
+ labeled_dict_centroids[current_centroids_undamaged], return_counts=True
)
- counted_labels_centroids_undamaged, label_counts_centroids_undamaged = np.unique(
- labeled_dict_centroids[current_centroids_undamaged], return_counts=True
- )
+ )
counted_labels_centroids_damaged, label_counts_centroids_damaged = np.unique(
labeled_dict_centroids[~current_centroids_undamaged], return_counts=True
- )
+ )
for index, row in df_label_colours.iterrows():
if row["idx"] in counted_labels_points_undamaged:
clpu = label_counts_points_undamaged[
@@ -268,34 +324,50 @@ def pixel_count_per_region(
left_hemi_counted_labels_points, left_hemi_label_counts_points = np.unique(
labels_dict_points[current_points_hemi == 1], return_counts=True
)
- left_hemi_counted_labels_centroids, left_hemi_label_counts_centroids = np.unique(
- labeled_dict_centroids[current_centroids_hemi == 1], return_counts=True
+ left_hemi_counted_labels_centroids, left_hemi_label_counts_centroids = (
+ np.unique(
+ labeled_dict_centroids[current_centroids_hemi == 1], return_counts=True
+ )
)
right_hemi_counted_labels_points, right_hemi_label_counts_points = np.unique(
labels_dict_points[current_points_hemi == 2], return_counts=True
)
- right_hemi_counted_labels_centroids, right_hemi_label_counts_centroids = np.unique(
- labeled_dict_centroids[current_centroids_hemi == 2], return_counts=True
+ right_hemi_counted_labels_centroids, right_hemi_label_counts_centroids = (
+ np.unique(
+ labeled_dict_centroids[current_centroids_hemi == 2], return_counts=True
+ )
)
for index, row in df_label_colours.iterrows():
# Left hemisphere
l_clp = (
- left_hemi_label_counts_points[left_hemi_counted_labels_points == row["idx"]][0]
- if row["idx"] in left_hemi_counted_labels_points else 0
+ left_hemi_label_counts_points[
+ left_hemi_counted_labels_points == row["idx"]
+ ][0]
+ if row["idx"] in left_hemi_counted_labels_points
+ else 0
)
l_clc = (
- left_hemi_label_counts_centroids[left_hemi_counted_labels_centroids == row["idx"]][0]
- if row["idx"] in left_hemi_counted_labels_centroids else 0
+ left_hemi_label_counts_centroids[
+ left_hemi_counted_labels_centroids == row["idx"]
+ ][0]
+ if row["idx"] in left_hemi_counted_labels_centroids
+ else 0
)
# Right hemisphere
r_clp = (
- right_hemi_label_counts_points[right_hemi_counted_labels_points == row["idx"]][0]
- if row["idx"] in right_hemi_counted_labels_points else 0
+ right_hemi_label_counts_points[
+ right_hemi_counted_labels_points == row["idx"]
+ ][0]
+ if row["idx"] in right_hemi_counted_labels_points
+ else 0
)
r_clc = (
- right_hemi_label_counts_centroids[right_hemi_counted_labels_centroids == row["idx"]][0]
- if row["idx"] in right_hemi_counted_labels_centroids else 0
+ right_hemi_label_counts_centroids[
+ right_hemi_counted_labels_centroids == row["idx"]
+ ][0]
+ if row["idx"] in right_hemi_counted_labels_centroids
+ else 0
)
# Skip empty counts
@@ -316,17 +388,23 @@ def pixel_count_per_region(
counts_per_label["right_hemi_object_count"].append(r_clc)
else:
- counted_labels_points, label_counts_points = np.unique(labels_dict_points, return_counts=True)
- counted_labels_centroids, label_counts_centroids = np.unique(labeled_dict_centroids, return_counts=True)
+ counted_labels_points, label_counts_points = np.unique(
+ labels_dict_points, return_counts=True
+ )
+ counted_labels_centroids, label_counts_centroids = np.unique(
+ labeled_dict_centroids, return_counts=True
+ )
for index, row in df_label_colours.iterrows():
clp = (
label_counts_points[counted_labels_points == row["idx"]][0]
- if row["idx"] in counted_labels_points else 0
+ if row["idx"] in counted_labels_points
+ else 0
)
clc = (
label_counts_centroids[counted_labels_centroids == row["idx"]][0]
- if row["idx"] in counted_labels_centroids else 0
+ if row["idx"] in counted_labels_centroids
+ else 0
)
if clp == 0 and clc == 0:
continue
@@ -342,7 +420,6 @@ def pixel_count_per_region(
return df_counts_per_label
-
def read_flat_file(file):
"""
Reads a flat file and produces an image array.
@@ -550,18 +627,22 @@ def flat_to_dataframe(image, damage_mask, hemi_mask, rescaleXY=None):
(0, 1, "damaged_region_area"),
]
else:
- combos = [(None, None, "region_area")] # compute for entire image with no filtering
+ combos = [
+ (None, None, "region_area")
+ ] # compute for entire image with no filtering
# Count pixels for each combo
for hemi_val, damage_val, col_name in combos:
mask = np.ones_like(image, dtype=bool)
if hemi_mask is not None:
- mask &= (hemi_mask == hemi_val)
+ mask &= hemi_mask == hemi_val
if damage_mask is not None:
- mask &= (damage_mask == damage_val)
+ mask &= damage_mask == damage_val
combo_df = count_pixels_per_label(image[mask], scale_factor)
combo_df = combo_df.rename(columns={"region_area": col_name})
- df_area_per_label = pd.merge(df_area_per_label, combo_df, on="idx", how="outer").fillna(0)
+ df_area_per_label = pd.merge(
+ df_area_per_label, combo_df, on="idx", how="outer"
+ ).fillna(0)
# If both masks exist, compute additional columns
if (hemi_mask is not None) and (damage_mask is not None):
diff --git a/PyNutil/processing/data_analysis.py b/PyNutil/processing/data_analysis.py
index bbe1ba4..2c1eeb4 100644
--- a/PyNutil/processing/data_analysis.py
+++ b/PyNutil/processing/data_analysis.py
@@ -71,18 +71,33 @@ def apply_custom_regions(df, custom_regions_dict):
# Define all possible columns to aggregate
possible_columns = [
- "pixel_count", "undamaged_pixel_count", "damaged_pixel_counts",
- "region_area", "undamaged_region_area", "damaged_region_area",
- "object_count", "undamaged_object_count", "damaged_object_count",
- "left_hemi_pixel_count", "left_hemi_undamaged_pixel_count",
- "left_hemi_damaged_pixel_count", "left_hemi_region_area",
- "left_hemi_undamaged_region_area", "left_hemi_damaged_region_area",
- "left_hemi_object_count", "left_hemi_undamaged_object_count",
- "left_hemi_damaged_object_count", "right_hemi_pixel_count",
- "right_hemi_undamaged_pixel_count", "right_hemi_damaged_pixel_count",
- "right_hemi_region_area", "right_hemi_undamaged_region_area",
- "right_hemi_damaged_region_area", "right_hemi_object_count",
- "right_hemi_undamaged_object_count", "right_hemi_damaged_object_count"
+ "pixel_count",
+ "undamaged_pixel_count",
+ "damaged_pixel_counts",
+ "region_area",
+ "undamaged_region_area",
+ "damaged_region_area",
+ "object_count",
+ "undamaged_object_count",
+ "damaged_object_count",
+ "left_hemi_pixel_count",
+ "left_hemi_undamaged_pixel_count",
+ "left_hemi_damaged_pixel_count",
+ "left_hemi_region_area",
+ "left_hemi_undamaged_region_area",
+ "left_hemi_damaged_region_area",
+ "left_hemi_object_count",
+ "left_hemi_undamaged_object_count",
+ "left_hemi_damaged_object_count",
+ "right_hemi_pixel_count",
+ "right_hemi_undamaged_pixel_count",
+ "right_hemi_damaged_pixel_count",
+ "right_hemi_region_area",
+ "right_hemi_undamaged_region_area",
+ "right_hemi_damaged_region_area",
+ "right_hemi_object_count",
+ "right_hemi_undamaged_object_count",
+ "right_hemi_damaged_object_count",
]
# Only include columns that actually exist in the DataFrame
@@ -102,7 +117,9 @@ def apply_custom_regions(df, custom_regions_dict):
# Calculate area fractions only if required columns exist
if "pixel_count" in grouped_df and "region_area" in grouped_df:
- grouped_df["area_fraction"] = grouped_df["pixel_count"] / grouped_df["region_area"]
+ grouped_df["area_fraction"] = (
+ grouped_df["pixel_count"] / grouped_df["region_area"]
+ )
if "undamaged_pixel_count" in grouped_df and "undamaged_region_area" in grouped_df:
grouped_df["undamaged_area_fraction"] = (
@@ -110,21 +127,34 @@ def apply_custom_regions(df, custom_regions_dict):
)
if "left_hemi_pixel_count" in grouped_df and "left_hemi_region_area" in grouped_df:
- grouped_df["left_hemi_area_fraction"] = grouped_df["left_hemi_pixel_count"] / grouped_df["left_hemi_region_area"]
+ grouped_df["left_hemi_area_fraction"] = (
+ grouped_df["left_hemi_pixel_count"] / grouped_df["left_hemi_region_area"]
+ )
- if "right_hemi_pixel_count" in grouped_df and "right_hemi_region_area" in grouped_df:
- grouped_df["right_hemi_area_fraction"] = grouped_df["right_hemi_pixel_count"] / grouped_df["right_hemi_region_area"]
+ if (
+ "right_hemi_pixel_count" in grouped_df
+ and "right_hemi_region_area" in grouped_df
+ ):
+ grouped_df["right_hemi_area_fraction"] = (
+ grouped_df["right_hemi_pixel_count"] / grouped_df["right_hemi_region_area"]
+ )
- if ("left_hemi_undamaged_pixel_count" in grouped_df and
- "left_hemi_undamaged_region_area" in grouped_df):
+ if (
+ "left_hemi_undamaged_pixel_count" in grouped_df
+ and "left_hemi_undamaged_region_area" in grouped_df
+ ):
grouped_df["left_hemi_undamaged_area_fraction"] = (
- grouped_df["left_hemi_undamaged_pixel_count"] / grouped_df["left_hemi_undamaged_region_area"]
+ grouped_df["left_hemi_undamaged_pixel_count"]
+ / grouped_df["left_hemi_undamaged_region_area"]
)
- if ("right_hemi_undamaged_pixel_count" in grouped_df and
- "right_hemi_undamaged_region_area" in grouped_df):
+ if (
+ "right_hemi_undamaged_pixel_count" in grouped_df
+ and "right_hemi_undamaged_region_area" in grouped_df
+ ):
grouped_df["right_hemi_undamaged_area_fraction"] = (
- grouped_df["right_hemi_undamaged_pixel_count"] / grouped_df["right_hemi_undamaged_region_area"]
+ grouped_df["right_hemi_undamaged_pixel_count"]
+ / grouped_df["right_hemi_undamaged_region_area"]
)
common_columns = [col for col in df.columns if col in grouped_df.columns]
@@ -146,7 +176,7 @@ def quantify_labeled_points(
centroids_hemi_labels,
per_point_undamaged,
per_centroid_undamaged,
- apply_damage_mask
+ apply_damage_mask,
):
"""
Aggregates labeled points into a summary table.
@@ -169,7 +199,7 @@ def quantify_labeled_points(
per_centroid_undamaged,
points_hemi_labels,
centroids_hemi_labels,
- apply_damage_mask
+ apply_damage_mask,
)
label_df = _combine_slice_reports(per_section_df, atlas_labels)
if not apply_damage_mask:
@@ -190,7 +220,7 @@ def _quantify_per_section(
per_centroid_undamaged,
points_hemi_labels,
centroids_hemi_labels,
- with_damage=False
+ with_damage=False,
):
"""
Quantifies labeled points per section.
@@ -225,7 +255,7 @@ def _quantify_per_section(
current_points_hemi,
current_centroids_hemi,
atlas_labels,
- with_damage
+ with_damage,
)
current_df_new = _merge_dataframes(current_df, ra, atlas_labels)
per_section_df.append(current_df_new)
@@ -248,22 +278,33 @@ def _merge_dataframes(current_df, ra, atlas_labels):
DataFrame: Merged DataFrame.
"""
cols_to_use = ra.columns.difference(atlas_labels.columns)
- all_region_df = atlas_labels.merge(ra[["idx",*cols_to_use]], on="idx", how="left")
+ all_region_df = atlas_labels.merge(ra[["idx", *cols_to_use]], on="idx", how="left")
cols_to_use = current_df.columns.difference(all_region_df.columns)
current_df_new = all_region_df.merge(
current_df[["idx", *cols_to_use]], on="idx", how="left"
)
- if "pixel_count" in current_df_new.columns and "region_area" in current_df_new.columns:
+ if (
+ "pixel_count" in current_df_new.columns
+ and "region_area" in current_df_new.columns
+ ):
current_df_new["area_fraction"] = (
current_df_new["pixel_count"] / current_df_new["region_area"]
)
- if "left_hemi_pixel_count" in current_df_new.columns and "left_hemi_region_area" in current_df_new.columns:
+ if (
+ "left_hemi_pixel_count" in current_df_new.columns
+ and "left_hemi_region_area" in current_df_new.columns
+ ):
current_df_new["left_hemi_area_fraction"] = (
- current_df_new["left_hemi_pixel_count"] / current_df_new["left_hemi_region_area"]
+ current_df_new["left_hemi_pixel_count"]
+ / current_df_new["left_hemi_region_area"]
)
- if "right_hemi_pixel_count" in current_df_new.columns and "right_hemi_region_area" in current_df_new.columns:
+ if (
+ "right_hemi_pixel_count" in current_df_new.columns
+ and "right_hemi_region_area" in current_df_new.columns
+ ):
current_df_new["right_hemi_area_fraction"] = (
- current_df_new["right_hemi_pixel_count"] / current_df_new["right_hemi_region_area"]
+ current_df_new["right_hemi_pixel_count"]
+ / current_df_new["right_hemi_region_area"]
)
current_df_new.fillna(0, inplace=True)
return current_df_new
@@ -289,18 +330,24 @@ def _combine_slice_reports(per_section_df, atlas_labels):
)
label_df["area_fraction"] = label_df["pixel_count"] / label_df["region_area"]
if "left_hemi_pixel_count" in label_df:
- label_df["left_hemi_area_fraction"] = label_df["left_hemi_pixel_count"] / label_df["left_hemi_region_area"]
- label_df["right_hemi_area_fraction"] = label_df["right_hemi_pixel_count"] / label_df["right_hemi_region_area"]
+ label_df["left_hemi_area_fraction"] = (
+ label_df["left_hemi_pixel_count"] / label_df["left_hemi_region_area"]
+ )
+ label_df["right_hemi_area_fraction"] = (
+ label_df["right_hemi_pixel_count"] / label_df["right_hemi_region_area"]
+ )
if "undamaged_region_area" in label_df:
label_df["undamaged_area_fraction"] = (
label_df["undamaged_pixel_count"] / label_df["undamaged_region_area"]
)
if ("left_hemi_pixel_count" in label_df) and ("undamaged_region_area" in label_df):
label_df["left_hemi_undamaged_area_fraction"] = (
- label_df["left_hemi_undamaged_pixel_count"] / label_df["left_hemi_undamaged_region_area"]
+ label_df["left_hemi_undamaged_pixel_count"]
+ / label_df["left_hemi_undamaged_region_area"]
)
label_df["right_hemi_undamaged_area_fraction"] = (
- label_df["right_hemi_undamaged_pixel_count"] / label_df["right_hemi_undamaged_region_area"]
+ label_df["right_hemi_undamaged_pixel_count"]
+ / label_df["right_hemi_undamaged_region_area"]
)
label_df.fillna(0, inplace=True)
label_df = label_df.set_index("idx")
diff --git a/PyNutil/processing/utils.py b/PyNutil/processing/utils.py
index 697ee6a..a73a6f7 100644
--- a/PyNutil/processing/utils.py
+++ b/PyNutil/processing/utils.py
@@ -239,15 +239,23 @@ def process_results(
centroids_len = [
len(centroids) if None not in centroids else 0 for centroids in centroids_list
]
- points_list = [points for points in points_list if (None not in points) and (len(points)!=0)]
+ points_list = [
+ points for points in points_list if (None not in points) and (len(points) != 0)
+ ]
centroids_list = [
- centroids for centroids in centroids_list if (None not in centroids)and (len(centroids!=0))
+ centroids
+ for centroids in centroids_list
+ if (None not in centroids) and (len(centroids != 0))
+ ]
+ points_labels = [pl for pl in points_labels if (None not in pl) and len(pl) != 0]
+ centroids_labels = [
+ cl for cl in centroids_labels if (None not in cl) and len(cl) != 0
+ ]
+ points_undamaged_list = [
+ pul for pul in points_undamaged_list if (None not in pul) and len(pul) != 0
]
- points_labels = [pl for pl in points_labels if (None not in pl) and len(pl)!=0]
- centroids_labels = [cl for cl in centroids_labels if (None not in cl) and len(cl)!=0]
- points_undamaged_list = [pul for pul in points_undamaged_list if (None not in pul) and len(pul)!=0]
centroids_undamaged_list = [
- cul for cul in centroids_undamaged_list if (None not in cul) and len(cul)!=0
+ cul for cul in centroids_undamaged_list if (None not in cul) and len(cul) != 0
]
if len(points_list) == 0:
diff --git a/gui/PyNutilGUI.py b/gui/PyNutilGUI.py
index d63dea5..c0fcc2b 100644
--- a/gui/PyNutilGUI.py
+++ b/gui/PyNutilGUI.py
@@ -201,7 +201,9 @@ class AnalysisWorker(QThread):
print("Analysis cancelled")
return
- pnt.get_coordinates(object_cutoff=0, apply_damage_mask=self.arguments["apply_damage_mask"])
+ pnt.get_coordinates(
+ object_cutoff=0, apply_damage_mask=self.arguments["apply_damage_mask"]
+ )
# Check if cancelled before continuing
if self.cancelled:
@@ -476,7 +478,9 @@ class PyNutilGUI(QMainWindow):
damage_markers_label = QLabel("Include Damage Quantification:")
self.include_damage_markers_checkbox = QCheckBox()
self.include_damage_markers_checkbox.setChecked(False)
- self.include_damage_markers_checkbox.stateChanged.connect(self.update_damage_markers_flag)
+ self.include_damage_markers_checkbox.stateChanged.connect(
+ self.update_damage_markers_flag
+ )
damage_markers_layout.addWidget(damage_markers_label)
damage_markers_layout.addWidget(self.include_damage_markers_checkbox)
diff --git a/tests/test_quantification.py b/tests/test_quantification.py
index 1f5acd8..c603bd6 100644
--- a/tests/test_quantification.py
+++ b/tests/test_quantification.py
@@ -41,8 +41,13 @@ class TestQuantification(unittest.TestCase):
pnt.save_analysis(save_path)
-test_case_files = ["brainglobe_atlas.json", "brainglobe_atlas_damage.json", "custom_atlas.json"]
+test_case_files = [
+ "brainglobe_atlas.json",
+ "brainglobe_atlas_damage.json",
+ "custom_atlas.json",
+]
for test_case_file in test_case_files:
+
def test_method(self, test_case_file=test_case_file):
self.run_test_case(test_case_file)
--
GitLab