Skip to content

Commit

Permalink
Apply ruff linting suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
jessicasyu committed Sep 20, 2024
1 parent 341c882 commit 6733be7
Show file tree
Hide file tree
Showing 19 changed files with 294 additions and 229 deletions.
308 changes: 163 additions & 145 deletions poetry.lock

Large diffs are not rendered by default.

46 changes: 44 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ python = "^3.9"
prefect = "^2.8.2"
numpy = "^1.24.2"
pandas = "^1.5.3"
aicsshparam = "^0.1.7"
aicsshparam = "^0.1.10"
vtk = "^9.2.5"
trimesh = "^3.18.3"
scikit-image = "^0.21.0"

[tool.poetry.group.dev.dependencies]
black = "^24.3.0"
Expand Down Expand Up @@ -68,11 +69,51 @@ module = [
]
ignore_missing_imports = true

[tool.ruff]
line-length = 100
target-version = "py39"

[tool.ruff.lint]
select = ["ALL"]
ignore = [
"COM812", # missing-trailing-comma
"D100", # undocumented-public-module
"D105", # undocumented-magic-method
"D107", # undocumented-public-init
"D202", # no-blank-line-after-function
"D203", # one-blank-line-before-class
"D212", # multi-line-summary-first-line
"D413", # blank-line-after-last-section
"D416", # section-name-ends-in-colon
]

[tool.ruff.lint.pylint]
max-args = 10

[tool.ruff.lint.per-file-ignores]
"tests/*.py" = [
"D", # pydocstyle
"PT009", # pytest-unittest-assertion
"PT027", # pytest-unittest-raises-assertion
"INP001", # implicit-namespace-package
"ANN201", # missing-return-type-undocumented-public-function
"S311", # suspicious-non-cryptographic-random-usage
"ANN001", # missing-type-function-argument
"ANN003", # missing-type-kwargs
"ANN202", # missing-type-args
]

[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"if TYPE_CHECKING:",
]

[tool.tox]
legacy_tox_ini = """
[tox]
isolated_build = True
envlist = py{39,310}, format, lint, typecheck
envlist = py{39,310,311}, format, lint, typecheck
skipsdist=True
[testenv]
Expand All @@ -88,6 +129,7 @@ commands =
[testenv:lint]
commands =
poetry run pylint --ignore-patterns=test.*?py src/ tests/ --fail-under=9.0
poetry run ruff check src/ tests/
[testenv:typecheck]
commands =
Expand Down
2 changes: 1 addition & 1 deletion src/abm_shape_collection/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Tasks for analyzing cell shapes including spherical harmonics and shape modes."""
"""Collection of tasks for analyzing cell shapes."""

from prefect import task

Expand Down
6 changes: 3 additions & 3 deletions src/abm_shape_collection/calculate_feature_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ def calculate_feature_statistics(

for feature in features:
# Extract values for specific component.
ref_values = ref_data[feature].values
values = data[feature].values
ref_values = ref_data[feature].to_numpy()
values = data[feature].to_numpy()

# Calculate KolmogorovSmirnov statistic.
# Calculate Kolmogorov-Smirnov statistic.
ks_result = ks_2samp(values, ref_values, mode="asymp")

statistics.append(
Expand Down
5 changes: 2 additions & 3 deletions src/abm_shape_collection/calculate_shape_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ def calculate_shape_statistics(
label: str = "shcoeffs",
) -> pd.DataFrame:
"""
Perform two-sample Kolmogorov-Smirnov test for goodness of fit on shape
components.
Perform two-sample Kolmogorov-Smirnov test for goodness of fit on shapes.
Parameters
----------
Expand Down Expand Up @@ -45,7 +44,7 @@ def calculate_shape_statistics(
ref_values = ref_transform[:, component]
values = transform[:, component]

# Calculate KolmogorovSmirnov statistic.
# Calculate Kolmogorov-Smirnov statistic.
ks_result = ks_2samp(values, ref_values, mode="asymp")

statistics.append(
Expand Down
2 changes: 1 addition & 1 deletion src/abm_shape_collection/construct_mesh_from_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

def construct_mesh_from_array(array: np.ndarray, reference: np.ndarray) -> vtkPolyData:
"""
Constructs a mesh from binary image array.
Construct a mesh from binary image array.
Parameters
----------
Expand Down
2 changes: 1 addition & 1 deletion src/abm_shape_collection/construct_mesh_from_coeffs.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def construct_mesh_from_coeffs(
scale: float = 1.0,
) -> vtkPolyData:
"""
Constructs a mesh from spherical harmonic coefficients.
Construct a mesh from spherical harmonic coefficients.
Parameters
----------
Expand Down
2 changes: 1 addition & 1 deletion src/abm_shape_collection/construct_mesh_from_points.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def construct_mesh_from_points(
suffix: str = "",
) -> vtkPolyData:
"""
Constructs mesh given PCA transformation points.
Construct mesh given PCA transformation points.
Parameters
----------
Expand Down
47 changes: 25 additions & 22 deletions src/abm_shape_collection/extract_mesh_projections.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

import tempfile
from typing import Optional, Union
from enum import Enum

import numpy as np
import trimesh
Expand All @@ -13,11 +15,20 @@
"""Mesh projection names, normals, and extent axes."""


class ProjectionType(Enum):
"""Projection slice types."""

SLICE = 1
"""Slice projection type."""

EXTENT = 2
"""Extent projection type."""


def extract_mesh_projections(
mesh: Union[vtkPolyData, trimesh.Trimesh],
slices: bool = True,
extents: bool = True,
offset: Optional[tuple[float, float, float]] = None,
mesh: vtkPolyData | trimesh.Trimesh,
projection_types: list[ProjectionType],
offset: tuple[float, float, float] | None = None,
) -> dict:
"""
Extract slices and/or extents from mesh.
Expand All @@ -31,10 +42,8 @@ def extract_mesh_projections(
----------
mesh
Mesh object.
slices
True to extract slices, False otherwise.
extents : bool, optional
True to extract extents, False otherwise.
projection_types
Mesh projection types.
offset
Mesh translation applied before extracting slices and/or meshes.
Expand All @@ -50,15 +59,13 @@ def extract_mesh_projections(
if offset is not None:
mesh.apply_translation(offset)

projections: dict[str, Union[list[list[list[float]]], dict[float, list[list[list[float]]]]]] = (
{}
)
projections: dict[str, list[list[list[float]]] | dict[float, list[list[list[float]]]]] = {}

if slices:
if ProjectionType.SLICE in projection_types:
for projection, normal, _ in PROJECTIONS:
projections[f"{projection}_slice"] = get_mesh_slice(mesh, normal)

if extents:
if ProjectionType.EXTENT in projection_types:
for projection, normal, index in PROJECTIONS:
projections[f"{projection}_extent"] = get_mesh_extent(mesh, normal, index)

Expand All @@ -67,7 +74,7 @@ def extract_mesh_projections(

def convert_vtk_to_trimesh(mesh: vtkPolyData) -> trimesh.Trimesh:
"""
Converts VTK polydata to trimesh object.
Convert VTK polydata to trimesh object.
Parameters
----------
Expand All @@ -85,9 +92,7 @@ def convert_vtk_to_trimesh(mesh: vtkPolyData) -> trimesh.Trimesh:
writer.SetFileTypeToASCII()
writer.SetFileName(f"{temp.name}.ply")
_ = writer.Write()
mesh = trimesh.load(f"{temp.name}.ply")

return mesh
return trimesh.load(f"{temp.name}.ply")


def get_mesh_slice(mesh: trimesh.Trimesh, normal: tuple[int, int, int]) -> list[list[list[float]]]:
Expand All @@ -108,8 +113,7 @@ def get_mesh_slice(mesh: trimesh.Trimesh, normal: tuple[int, int, int]) -> list[
"""

mesh_slice = mesh.section_multiplane((0, 0, 0), normal, [0])
points = [[list(point) for point in entity] for entity in mesh_slice[0].discrete]
return points
return [[list(point) for point in entity] for entity in mesh_slice[0].discrete]


def get_mesh_extent(
Expand All @@ -136,9 +140,8 @@ def get_mesh_extent(
layers = int(mesh.extents[index] + 2)
plane_indices = list(np.arange(-layers, layers + 1, 0.5))
mesh_extents = mesh.section_multiplane((0, 0, 0), normal, plane_indices)
points = {
return {
index: [[list(point) for point in entity] for entity in mesh_extent.discrete]
for mesh_extent, index in zip(mesh_extents, plane_indices)
if mesh_extent is not None
}
return points
14 changes: 8 additions & 6 deletions src/abm_shape_collection/extract_mesh_wireframe.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
from typing import Optional, Union
from __future__ import annotations

from typing import TYPE_CHECKING

import trimesh
from vtk import vtkPolyData # pylint: disable=no-name-in-module

from abm_shape_collection.extract_mesh_projections import convert_vtk_to_trimesh

if TYPE_CHECKING:
import trimesh


def extract_mesh_wireframe(
mesh: Union[vtkPolyData, trimesh.Trimesh], offset: Optional[tuple[float, float, float]] = None
mesh: vtkPolyData | trimesh.Trimesh, offset: tuple[float, float, float] | None = None
) -> list[list[tuple[float, float, float]]]:
"""
Extract wireframe edges from mesh.
Expand All @@ -32,9 +36,7 @@ def extract_mesh_wireframe(
mesh.apply_translation(offset)

all_edges = [[tuple(mesh.vertices[a]), tuple(mesh.vertices[b])] for a, b in mesh.edges]
wireframe = [
return [
[(x1, y1, z1), (x2, y2, z2)]
for (x1, y1, z1), (x2, y2, z2) in {frozenset(edge) for edge in all_edges}
]

return wireframe
10 changes: 5 additions & 5 deletions src/abm_shape_collection/extract_shape_modes.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def extract_shape_modes(
offsets = calculate_region_offsets(data, region)

for component in range(components):
point_vector = np.zeros((components))
point_vector = np.zeros(components)

for point in map_points:
point_bin = np.digitize(point, bin_edges)
Expand Down Expand Up @@ -122,10 +122,10 @@ def calculate_region_offsets(data: pd.DataFrame, region: str) -> dict:
if region == "DEFAULT":
return {}

x_deltas = data[f"CENTER_X.{region}"].values - data["CENTER_X"].values
y_deltas = data[f"CENTER_Y.{region}"].values - data["CENTER_Y"].values
z_deltas = data[f"CENTER_Z.{region}"].values - data["CENTER_Z"].values
angles = data["angle"].values * np.pi / 180.0
x_deltas = data[f"CENTER_X.{region}"].to_numpy() - data["CENTER_X"].to_numpy()
y_deltas = data[f"CENTER_Y.{region}"].to_numpy() - data["CENTER_Y"].to_numpy()
z_deltas = data[f"CENTER_Z.{region}"].to_numpy() - data["CENTER_Z"].to_numpy()
angles = data["angle"].to_numpy() * np.pi / 180.0

sin_angles = np.sin(angles)
cos_angles = np.cos(angles)
Expand Down
2 changes: 1 addition & 1 deletion src/abm_shape_collection/extract_voxel_contours.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def extract_voxel_contours(
x_bounds = width
y_bounds = height

array = np.full((x_bounds, y_bounds), False)
array = np.full((x_bounds, y_bounds), fill_value=False)
array[tuple(np.transpose(list(voxels)))] = True

edges = get_array_edges(array)
Expand Down
4 changes: 1 addition & 3 deletions src/abm_shape_collection/get_shape_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,4 @@ def get_shape_properties(array: np.ndarray, properties: list[str]) -> dict:
flattened_array = array.max(axis=0)

properties_dict = regionprops_table(flattened_array, properties=properties)
props = {key: value[0] for key, value in properties_dict.items()}

return props
return {key: value[0] for key, value in properties_dict.items()}
6 changes: 3 additions & 3 deletions src/abm_shape_collection/make_voxels_array.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
from typing import Optional
from __future__ import annotations

import numpy as np


def make_voxels_array(
voxels: list[tuple[int, int, int]],
reference: Optional[list[tuple[int, int, int]]] = None,
reference: list[tuple[int, int, int]] | None = None,
scale: int = 1,
) -> np.ndarray:
"""
Converts list of voxels in binary image array.
Convert list of voxels to a binary image array.
Parameters
----------
Expand Down
10 changes: 6 additions & 4 deletions tests/abm_shape_collection/test_calculate_feature_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ def test_calculate_feature_statistics(self):
data_length = 5
ref_length = 10

rng = np.random.default_rng()

feature_a = "feature_a"
feature_a_data = np.random.random_sample((data_length,))
feature_a_ref = np.random.random_sample((ref_length,))
feature_a_data = rng.random((data_length,))
feature_a_ref = rng.random((ref_length,))
feature_a_len = len(feature_a_data)
feature_a_ks = ks_2samp(feature_a_data, feature_a_ref, mode="asymp")

feature_b = "feature_b"
feature_b_data = np.random.random_sample((data_length,))
feature_b_ref = np.random.random_sample((ref_length,))
feature_b_data = rng.random((data_length,))
feature_b_ref = rng.random((ref_length,))
feature_b_len = len(feature_b_data)
feature_b_ks = ks_2samp(feature_b_data, feature_b_ref, mode="asymp")

Expand Down
22 changes: 12 additions & 10 deletions tests/abm_shape_collection/test_calculate_shape_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,28 @@ def test_calculate_shape_statistics(self):
data_length = 6
ref_length = 10

rng = np.random.default_rng()

data = pd.DataFrame(
{
f"{label}_a": np.random.random_sample((data_length,)),
f"{label}_b": np.random.random_sample((data_length,)),
f"{label}_c": np.random.random_sample((data_length,)),
f"{label}_a": rng.random((data_length,)),
f"{label}_b": rng.random((data_length,)),
f"{label}_c": rng.random((data_length,)),
}
)
ref_data = pd.DataFrame(
{
f"{label}_a": np.random.random_sample((ref_length,)),
f"{label}_b": np.random.random_sample((ref_length,)),
f"{label}_c": np.random.random_sample((ref_length,)),
f"{label}_a": rng.random((ref_length,)),
f"{label}_b": rng.random((ref_length,)),
f"{label}_c": rng.random((ref_length,)),
}
)

pc1_data = np.random.random_sample((data_length,))
pc1_ref = np.random.random_sample((ref_length,))
pc1_data = rng.random((data_length,))
pc1_ref = rng.random((ref_length,))

pc2_data = np.random.random_sample((data_length,))
pc2_ref = np.random.random_sample((ref_length,))
pc2_data = rng.random((data_length,))
pc2_ref = rng.random((ref_length,))

mock_transform = {
data_length: np.array([pc1_data, pc2_data]).T,
Expand Down
Loading

0 comments on commit 6733be7

Please sign in to comment.