Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

save the scaling information in the motile_run and load it back in wh… #67

Merged
merged 5 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 32 additions & 16 deletions src/motile_plugin/backend/motile_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
OUT_SEG_FILEANME = "output_segmentation.npy"
TRACKS_FILENAME = "tracks.json"
GAPS_FILENAME = "gaps.txt"
SCALE_FILENAME = "scale.txt"


class MotileRun(BaseModel):
Expand All @@ -33,7 +34,7 @@ class MotileRun(BaseModel):
input_points: np.ndarray | None = None
tracks: Tracks | None = None
time: datetime = datetime.now()
gaps: list[float] = []
gaps: list[float] | None = None
status: str = "done"
scale: list[float] | None = None
# pydantic does not check numpy arrays
Expand Down Expand Up @@ -99,7 +100,12 @@ def save(self, base_path: str | Path) -> Path:
)
if self.tracks.graph is not None:
self._save_tracks_graph(run_dir, self.tracks.graph)
self._save_gaps(run_dir)
self._save_list(
list_to_save=self.gaps, run_dir=run_dir, filename=GAPS_FILENAME
)
self._save_list(
list_to_save=self.scale, run_dir=run_dir, filename=SCALE_FILENAME
)
return run_dir

@classmethod
Expand Down Expand Up @@ -138,7 +144,8 @@ def load(cls, run_dir: Path | str, output_required: bool = True):
run_dir, required=output_required
)
tracks = Tracks(graph=tracks_graph, segmentation=output_segmentation)
gaps = cls._load_gaps(run_dir)
gaps = cls._load_list(run_dir=run_dir, filename=GAPS_FILENAME, required=False)
scale = cls._load_list(run_dir=run_dir, filename=SCALE_FILENAME, required=False)
return cls(
run_name=run_name,
solver_params=params,
Expand All @@ -147,6 +154,7 @@ def load(cls, run_dir: Path | str, output_required: bool = True):
tracks=tracks,
time=time,
gaps=gaps,
scale=scale,
)

def _save_params(self, run_dir: Path):
Expand Down Expand Up @@ -265,25 +273,32 @@ def _load_tracks_graph(
else:
return None

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)))
def _save_list(
self, list_to_save: list | None, run_dir: Path, filename: str
):

if list_to_save is None:
return
list_file = run_dir / filename
with open(list_file, "w") as f:
f.write(",".join(map(str, list_to_save)))

@staticmethod
def _load_gaps(run_dir, required: bool = True) -> list[float]:
gaps_file = run_dir / GAPS_FILENAME
if gaps_file.is_file():
with open(gaps_file) as f:
def _load_list(
run_dir: Path, filename: str, required: bool = True
) -> list[float]:
list_file = run_dir / filename
if list_file.is_file():
with open(list_file) as f:
file_content = f.read()
if file_content == "":
return []
gaps = list(map(float, file_content.split(",")))
return gaps
return None
list_values = list(map(float, file_content.split(",")))
return list_values
elif required:
raise FileNotFoundError(f"No gaps found at {gaps_file}")
raise FileNotFoundError(f"No content found at {list_file}")
else:
return []
return None

def delete(self, base_path: str | Path):
"""Delete this run from the file system. Will look inside base_path
Expand All @@ -301,4 +316,5 @@ def delete(self, base_path: str | Path):
(run_dir / OUT_SEG_FILEANME).unlink()
(run_dir / TRACKS_FILENAME).unlink()
(run_dir / GAPS_FILENAME).unlink()
(run_dir / SCALE_FILENAME).unlink()
run_dir.rmdir()
2 changes: 2 additions & 0 deletions src/motile_plugin/widgets/motile/motile_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ def _on_solver_event(self, run: MotileRun, event_data: dict) -> None:
elif event_type in ["MIPSOL", "BESTSOLFOUND"]:
run.status = "solving"
gap = event_data["gap"]
if run.gaps is None:
run.gaps = []
run.gaps.append(gap)
self.solver_update.emit()

Expand Down
3 changes: 3 additions & 0 deletions tests/backend/test_motile_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ def test_save_load(tmp_path, graph_2d):
segmentation[i][0:5, 0:5] = i

run_name = "test"
scale = [1.0, 2.0, 3.0]
run = MotileRun(
run_name=run_name,
solver_params=SolverParams(),
tracks=Tracks(graph=graph_2d, segmentation=segmentation),
scale=scale,
)
path = run.save(tmp_path)
newrun = MotileRun.load(path)
Expand All @@ -24,4 +26,5 @@ def test_save_load(tmp_path, graph_2d):
assert run.run_name == newrun.run_name
assert run.time.replace(microsecond=0) == newrun.time
assert run.gaps == newrun.gaps
assert run.scale == newrun.scale
assert run.solver_params == newrun.solver_params
Loading