Skip to content

Commit

Permalink
Make ruff and black happy
Browse files Browse the repository at this point in the history
  • Loading branch information
cmalinmayor committed Apr 29, 2024
1 parent f41e742 commit d7c742d
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 76 deletions.
39 changes: 21 additions & 18 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,6 @@ target-version = ['py38', 'py39', 'py310']

[tool.ruff]
line-length = 79
select = [
"E", "F", "W", #flake8
"UP", # pyupgrade
"I", # isort
"BLE", # flake8-blind-exception
"B", # flake8-bugbear
"A", # flake8-builtins
"C4", # flake8-comprehensions
"ISC", # flake8-implicit-str-concat
"G", # flake8-logging-format
"PIE", # flake8-pie
"SIM", # flake8-simplify
]
ignore = [
"E501", # line too long. let black handle this
"UP006", "UP007", # type annotation. As using magicgui require runtime type annotation then we disable this.
"SIM117", # flake8-simplify - some of merged with statements are not looking great with black, reanble after drop python 3.9
]

exclude = [
".bzr",
Expand All @@ -54,3 +36,24 @@ exclude = [

target-version = "py38"
fix = true

[tool.ruff.lint]
select = [
"E", "F", "W", #flake8
"UP", # pyupgrade
"I", # isort
"BLE", # flake8-blind-exception
"B", # flake8-bugbear
"A", # flake8-builtins
"C4", # flake8-comprehensions
"ISC", # flake8-implicit-str-concat
"G", # flake8-logging-format
"PIE", # flake8-pie
"SIM", # flake8-simplify
]

ignore = [
"E501", # line too long. let black handle this
"UP006", "UP007", # type annotation. As using magicgui require runtime type annotation then we disable this.
"SIM117", # flake8-simplify - some of merged with statements are not looking great with black, reanble after drop python 3.9
]
4 changes: 1 addition & 3 deletions src/motile_plugin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
__version__ = "0.0.1"
from .widgets.motile_widget import MotileWidget

__all__ = (
"MotileWidget",
)
__all__ = ("MotileWidget",)
5 changes: 4 additions & 1 deletion src/motile_plugin/_graph_layer_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ def to_napari_graph_layer(graph, name, loc_keys=("t", "z", "y", "x")):
napari_id += 1
num_nodes = napari_id

edges = [[nx_id_to_napari_id[s], nx_id_to_napari_id[t]] for s, t in graph.edges()]
edges = [
[nx_id_to_napari_id[s], nx_id_to_napari_id[t]]
for s, t in graph.edges()
]
coords = [
get_location(
graph.nodes[napari_id_to_nx_id[nap_id]], loc_keys=loc_keys
Expand Down
52 changes: 43 additions & 9 deletions src/motile_plugin/_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ def multi_hypothesis_segmentation_2d():
"""
frame_shape = (100, 100)
total_shape = (2, 2, *frame_shape) # 2 time points, 2 hypotheses layers, H, W
total_shape = (
2,
2,
*frame_shape,
) # 2 time points, 2 hypotheses layers, H, W
segmentation = np.zeros(total_shape, dtype="int32")
# make frame with one cell in center with label 1 (hypo 1)
rr0, cc0 = disk(center=(50, 50), radius=20, shape=frame_shape)
Expand Down Expand Up @@ -90,8 +94,16 @@ def graph_2d():
),
]
edges = [
("0_1", "1_1", {EdgeAttr.DISTANCE.value: 42.43, EdgeAttr.IOU.value: 0.0}),
("0_1", "1_2", {EdgeAttr.DISTANCE.value: 11.18, EdgeAttr.IOU.value: 0.395}),
(
"0_1",
"1_1",
{EdgeAttr.DISTANCE.value: 42.43, EdgeAttr.IOU.value: 0.0},
),
(
"0_1",
"1_2",
{EdgeAttr.DISTANCE.value: 11.18, EdgeAttr.IOU.value: 0.395},
),
]
graph.add_nodes_from(nodes)
graph.add_edges_from(edges)
Expand Down Expand Up @@ -159,8 +171,16 @@ def multi_hypothesis_graph_2d():
]

edges = [
("0_0_1", "1_0_1", {EdgeAttr.DISTANCE.value: 42.426, EdgeAttr.IOU.value: 0.0}),
("0_0_1", "1_1_1", {EdgeAttr.DISTANCE.value: 43.011, EdgeAttr.IOU.value: 0.0}),
(
"0_0_1",
"1_0_1",
{EdgeAttr.DISTANCE.value: 42.426, EdgeAttr.IOU.value: 0.0},
),
(
"0_0_1",
"1_1_1",
{EdgeAttr.DISTANCE.value: 43.011, EdgeAttr.IOU.value: 0.0},
),
(
"0_0_1",
"1_0_2",
Expand All @@ -171,9 +191,21 @@ def multi_hypothesis_graph_2d():
"1_1_2",
{EdgeAttr.DISTANCE.value: 11.180, EdgeAttr.IOU.value: 0.4768},
),
("0_1_1", "1_0_1", {EdgeAttr.DISTANCE.value: 43.011, EdgeAttr.IOU.value: 0.0}),
("0_1_1", "1_1_1", {EdgeAttr.DISTANCE.value: 42.426, EdgeAttr.IOU.value: 0.0}),
("0_1_1", "1_0_2", {EdgeAttr.DISTANCE.value: 15.0, EdgeAttr.IOU.value: 0.2402}),
(
"0_1_1",
"1_0_1",
{EdgeAttr.DISTANCE.value: 43.011, EdgeAttr.IOU.value: 0.0},
),
(
"0_1_1",
"1_1_1",
{EdgeAttr.DISTANCE.value: 42.426, EdgeAttr.IOU.value: 0.0},
),
(
"0_1_1",
"1_0_2",
{EdgeAttr.DISTANCE.value: 15.0, EdgeAttr.IOU.value: 0.2402},
),
(
"0_1_1",
"1_1_2",
Expand All @@ -188,7 +220,9 @@ def multi_hypothesis_graph_2d():
def sphere(center, radius, shape):
assert len(center) == len(shape)
indices = np.moveaxis(np.indices(shape), 0, -1) # last dim is the index
distance = np.linalg.norm(np.subtract(indices, np.asarray(center)), axis=-1)
distance = np.linalg.norm(
np.subtract(indices, np.asarray(center)), axis=-1
)
mask = distance <= radius
return mask

Expand Down
3 changes: 1 addition & 2 deletions src/motile_plugin/_tests/test_solver.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

from motile_plugin.backend.solve import solve
from motile_plugin.backend.solver_params import SolverParamsWidget

Expand All @@ -12,11 +11,11 @@ def test_solve_2d(segmentation_2d, graph_2d):
soln_graph = solve(params, segmentation_2d)
assert set(soln_graph.nodes) == set(graph_2d.nodes)


def test_solve_3d(segmentation_3d, graph_3d):
params = SolverParamsWidget()
params.merge_cost = None
params.appear_cost = None
params.disappear_cost = None
soln_graph = solve(params, segmentation_3d)
assert set(soln_graph.nodes) == set(graph_3d.nodes)

31 changes: 17 additions & 14 deletions src/motile_plugin/backend/motile_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@


class MotileRun(BaseModel):
"""An object representing a motile tracking run.
"""
"""An object representing a motile tracking run."""

run_name: str
solver_params: SolverParams
input_segmentation: np.ndarray | None = None
Expand All @@ -40,20 +40,26 @@ def _make_directory(time, run_name):
def _unpack_directory(directory):
stamp_len = len(datetime.now().strftime(STAMP_FORMAT))
stamp = directory[0:stamp_len]
run_name = directory[stamp_len+1:]
run_name = directory[stamp_len + 1 :]
try:
time = datetime.strptime(stamp, STAMP_FORMAT)
except:
raise ValueError(f"Cannot unpack directory {directory} into timestamp and run name.")
except ValueError as e:
raise ValueError(
f"Cannot unpack directory {directory} into timestamp and run name."
) from e
return time, run_name

def save(self, base_path: str | Path):
base_path = Path(base_path)
run_dir = base_path / self._make_directory(self.time, self.run_name)
Path.mkdir(run_dir)
self._save_params(run_dir)
self._save_segmentation(run_dir, IN_SEG_FILEANME, self.input_segmentation)
self._save_segmentation(run_dir, OUT_SEG_FILEANME, self.output_segmentation)
self._save_segmentation(
run_dir, IN_SEG_FILEANME, self.input_segmentation
)
self._save_segmentation(
run_dir, OUT_SEG_FILEANME, self.output_segmentation
)
self._save_tracks(run_dir)
if self.gaps is not None:
self._save_gaps(run_dir)
Expand All @@ -80,7 +86,7 @@ def load(cls, run_dir: Path | str):

def _save_params(self, run_dir):
params_file = run_dir / PARAMS_FILENAME
with open(params_file, 'w') as f:
with open(params_file, "w") as f:
json.dump(self.solver_params.__dict__, f)

@staticmethod
Expand Down Expand Up @@ -110,7 +116,7 @@ def _load_segmentation(

def _save_tracks(self, run_dir: Path):
tracks_file = run_dir / TRACKS_FILENAME
with open(tracks_file, 'w') as f:
with open(tracks_file, "w") as f:
json.dump(nx.node_link_data(self.tracks), f)

@staticmethod
Expand All @@ -127,8 +133,8 @@ def _load_tracks(run_dir: Path, required: bool = True) -> nx.DiGraph:

def _save_gaps(self, run_dir: Path):
gaps_file = run_dir / GAPS_FILENAME
with open(gaps_file, 'w') as f:
f.write(','.join(map(str, self.gaps)))
with open(gaps_file, "w") as f:
f.write(",".join(map(str, self.gaps)))

@staticmethod
def _load_gaps(run_dir, required: bool = True) -> list[float]:
Expand All @@ -142,8 +148,6 @@ def _load_gaps(run_dir, required: bool = True) -> list[float]:
else:
return None



def delete(self, base_path: str | Path):
base_path = Path(base_path)
run_dir = base_path / self._make_directory(self.time, self.run_name)
Expand All @@ -155,4 +159,3 @@ def delete(self, base_path: str | Path):
(run_dir / TRACKS_FILENAME).unlink()
(run_dir / GAPS_FILENAME).unlink()
run_dir.rmdir()

2 changes: 1 addition & 1 deletion src/motile_plugin/widgets/motile_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def update_napari_layers(self, run: MotileRun) -> None:
run.output_segmentation[:, 0], name=run.run_name + "_seg"
)
if run.tracks is None or run.tracks.number_of_nodes() == 0:
warn("No tracks found for run {run.run_name}")
warn(f"No tracks found for run {run.run_name}", stacklevel=2)
self.tracks_layer = None
else:
track_data, track_props, track_edges = to_napari_tracks_layer(
Expand Down
30 changes: 22 additions & 8 deletions src/motile_plugin/widgets/run_editor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

from warnings import warn

import numpy as np
Expand All @@ -23,15 +22,20 @@

class RunEditor(QWidget):
create_run = Signal(MotileRun)

def __init__(self, run_name, solver_params, layers, multiseg=False):
# TODO: Don't pass static layers
super().__init__()
self.run_name: QLineEdit
self.layers: list
self.layer_selection_box: QComboBox
self.solver_params_widget = SolverParamsWidget(solver_params, editable=True)
self.solver_params_widget = SolverParamsWidget(
solver_params, editable=True
)
main_layout = QVBoxLayout()
main_layout.addWidget(self._ui_select_labels_layer(layers, multiseg=multiseg))
main_layout.addWidget(
self._ui_select_labels_layer(layers, multiseg=multiseg)
)
main_layout.addWidget(self.solver_params_widget)
main_layout.addWidget(self._ui_run_motile(run_name))
self.setLayout(main_layout)
Expand All @@ -42,9 +46,13 @@ def _ui_select_labels_layer(self, layers, multiseg=False) -> QGroupBox:
layer_layout = QHBoxLayout()
self.layer_selection_box = QComboBox()
if multiseg:
self.layer_selection_box.setSelectionMode(QAbstractItemView.SelectionMode.MultiSelection)
self.layer_selection_box.setSelectionMode(
QAbstractItemView.SelectionMode.MultiSelection
)
self.update_labels_layers(layers)
self.layer_selection_box.setToolTip("Select the labels layer you want to use for tracking")
self.layer_selection_box.setToolTip(
"Select the labels layer you want to use for tracking"
)
layer_layout.addWidget(self.layer_selection_box)
layer_group.setLayout(layer_layout)
return layer_group
Expand Down Expand Up @@ -76,7 +84,9 @@ def _ui_run_motile(self, run_name) -> QGroupBox:
# Generate Tracks button
generate_tracks_btn = QPushButton("Create Run")
generate_tracks_btn.clicked.connect(self.emit_run)
generate_tracks_btn.setToolTip("Run tracking. Might take minutes or longer for larger samples.")
generate_tracks_btn.setToolTip(
"Run tracking. Might take minutes or longer for larger samples."
)
run_layout.addWidget(generate_tracks_btn)

# Add running widget
Expand All @@ -93,12 +103,16 @@ def get_run(self):
run_name = self.get_run_name()
input_layer = self.get_labels_layer()
if input_layer is None:
warn("No input labels layer selected")
warn("No input labels layer selected", stacklevel=2)
return None
input_seg = np.expand_dims(input_layer.data, 1)
print(f"{input_seg.shape=}")
params = self.solver_params_widget.solver_params.copy()
return MotileRun(run_name=run_name, solver_params=params, input_segmentation=input_seg)
return MotileRun(
run_name=run_name,
solver_params=params,
input_segmentation=input_seg,
)

def emit_run(self):
run = self.get_run()
Expand Down
Loading

0 comments on commit d7c742d

Please sign in to comment.