Skip to content

Deprecate motile run - #447

Merged
cmalinmayor merged 24 commits into
mainfrom
deprecate-motile-run
Aug 18, 2026
Merged

Deprecate motile run#447
cmalinmayor merged 24 commits into
mainfrom
deprecate-motile-run

Conversation

@cmalinmayor

@cmalinmayor cmalinmayor commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Prerequisite for splitting out napari-track-edit, which I'll do as soon as this is merged (or rather, I'll start to do and then find a bunch of other changes needed)

Design decisions:

  • Difference between internal save/load and external import/export - For save/load, we can make and enforce assumptions about metadata and format (geff format, masks/bboxes instead of segmentation array, Features are present), with support for loading old formats. For import/export, we cannot make nearly as many assumptions, and we support more formats.
  • Users can choose internal save path, including name of the geff, but in a persistent widget, not a pop-up dialog. Eventually, this save location can be persisted in settings across sessions. Overwriting an exisitng geff will create a pop-up confirmation.
  • MotileRun behavior changes - instead of a timestamped directory with tracks.geff and solution_params.json inside of it, the extra metadata json files go inside the geff, so that it looks the same as other geffs from the outside.

@codecov-commenter

codecov-commenter commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.22485% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.67%. Comparing base (0270d12) to head (fc677d0).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...racker/data_views/views_coordinator/tracks_list.py 97.24% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #447      +/-   ##
==========================================
+ Coverage   88.44%   88.67%   +0.23%     
==========================================
  Files          58       59       +1     
  Lines        5606     5732     +126     
==========================================
+ Hits         4958     5083     +125     
- Misses        648      649       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cmalinmayor
cmalinmayor marked this pull request as ready for review July 29, 2026 14:47
@cmalinmayor
cmalinmayor requested a review from AnniekStok July 29, 2026 14:47
@cmalinmayor
cmalinmayor requested a review from TeunHuijben July 29, 2026 18:25

@TeunHuijben TeunHuijben left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cmalinmayor, I think it looks good! A quick test shows that loading a geff via both paths works.

Two comments:

  1. In the UI, "Tracks (geff)" and "External tracks from geff" are different, but from the user's perspective, they might be hard to distinguish (how is one geff different from another geff)?
  2. We have to be careful with the TracksList.tracks_loaded signal, especially the Path part of it. Because, depending on which import route is chosen, the Path is sometimes the .geff file, and sometimes the root folder of a project (because find_geff_group found the geff in that folder upon loading). So listeners to the signal should be aware that they can get all kind of Paths their way.

if isinstance(tracks, MotileRun):
directory = tracks.save(directory)
else:
write_to_geff(tracks, directory, overwrite=True)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure overwrite=True is good here? What if directory is a normal folder, and during loading we found a geff in there. Does this mean we only overwite the geff, or the entire directory? I think we have to be very careful, since with the new loading strategy, directory can be a lot of things (any folder containing a geff, a .zarr with a geff inside, the .geff store itself, etc.)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah I actually had a local unpushed commit where I made a separate dialog for the "internal" format. But I agree that this is confusing, partially because the internal GEFF save will hopefully be replaced with the persistent sql graph soon..... 🙃 I'll clean it up a bit and clarify the two paths with docstirngs and docs

@TeunHuijben

Copy link
Copy Markdown
Collaborator

Another change I made (that showed up in the benchmarks): The Tracks object has to actively disconnect from previous TrackViewers when displayed in a new one:

"The missing disconnect was always a bug: a TracksViewer signed up for a Tracks object's signals and never signed off. Wrapping each Tracks in a fresh MotileRun hid it, because every wrapper started with no subscribers. Now that we pass the Tracks through directly, stale TracksViewers pile up on the same object and every signal updates all of them."

@TeunHuijben

Copy link
Copy Markdown
Collaborator

Another point: Claude found a discrepancy in the save+load roundtrips, in that the scale is not surviving the geff-roundtrip. Not blocking this PR, but I made a separate PR in funtracks to fix this funkelab/funtracks#267

@TeunHuijben

Copy link
Copy Markdown
Collaborator

@cmalinmayor, thanks for the changes! Should I give this a review? or are you working on it?

@cmalinmayor

Copy link
Copy Markdown
Collaborator Author

@cmalinmayor, thanks for the changes! Should I give this a review? or are you working on it?

I don't remember if I was done or not 😆 so go ahead and review!

@AnniekStok AnniekStok left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a 'user' test: opening an old motile run, changing it, and saving and loading again in different formats, all worked as expected 🎉

Just reminding you that you wanted to update the docs for this as well :)

@cmalinmayor
cmalinmayor merged commit 9546021 into main Aug 18, 2026
22 checks passed
@TeunHuijben
TeunHuijben deleted the deprecate-motile-run branch August 18, 2026 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants