diff --git a/README.md b/README.md index e29ae9c..82f8228 100644 --- a/README.md +++ b/README.md @@ -27,13 +27,13 @@ and updated for 2024 by Caroline Malin-Mayor. Here we will introduce a modern formulation of tracking-by-detection. -You will learn -- to **store and visualize** tracking results with `napari`. -- how linking with global context can be modeled and solved efficiently as a **network flow** using `motile` ([docs here](https://funkelab.github.io/motile/)) for a small-scale problem. -- to adapt the previous formulation to allow for **arbitrary track starting and ending points**. -- to extend the ILP to properly model **cell divisions**. -- to tune the **hyperparameters** of the ILP. - +You will learn: +- how to represent tracking inputs and outputs as a graph using the `networkx` library +- how to use [`motile`](https://funkelab.github.io/motile/) to solve tracking via global optimization +- how to visualize tracking inputs and outputs +- how to evaluate tracking and understand common tracking metrics +- how to add custom costs to the candidate graph and incorpate them into `motile` +- how to learn the best **hyperparameters** of the ILP using an SSVM (bonus) ### Bonus: Tracking with two-step Linear Assignment Problem (LAP) diff --git a/solution.py b/solution.py index 231be5e..f5d3004 100644 --- a/solution.py +++ b/solution.py @@ -37,7 +37,7 @@ # ### YOUR CODE HERE ### # ``` # -# This notebook was originally written by Benjamin Gallusser. +# This notebook was originally written by Benjamin Gallusser, and was edited for 2024 by Caroline Malin-Mayor. # %% [markdown] # ## Import packages @@ -96,6 +96,22 @@ probabilities = data_root["probs"][:] +# %% [markdown] +# ## Task 1: Read in the ground truth graph +# The ground truth tracks are stored in a CSV with five columns: id, time, x, y, and parent_id. +# +# Each row in the CSV represents a detection at location (time, x, y) with the given id. +# If the parent_id is not -1, it represents the id of the parent in the previous time frame. +# For cell tracking, tracks can usually be stored in this format, because there is no merging. +# With merging, a more complicated data struture would be needed. +# +#
Use the motile quickstart example to set up a basic motile pipeline for our task. Then run the function and find hyperparmeters that give you tracks.
#Now that you have ways to determine how good the output is, try adjusting your weights or using different combinations of Costs and Constraints to get better results. For now, stick to those implemented in `motile`, but consider what kinds of custom costs and constraints you could implement to improve performance, since that is what we will do next!
#For this task, we need to determine the "expected" amount of motion, then add an attribute to our candidate edges that represents distance from the expected motion direction. Finally, we can incorporate that feature into the ILP via the EdgeSelection cost and see if it improves performance.
#