You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit c2b9bb8
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
9
9
10
10
### Added
11
11
12
+
- **Native 3-D files: Anipose and DeepLabCut 3-D.** Two new readers (`anipose` for `pose-3d` CSV, `deeplabcut_3d` for the triangulated tables; both built from the published layouts and tested on synthetic files only, so labelled *synthetic only*) give sessions with an absolute z in the project's length unit. `fps` and `unit` (mm, cm, m, in) are required options and never guessed (Anipose proposes `mm`, DeepLabCut 3-D proposes nothing); `target_unit` (default `cm`), `keypoint`, `likelihood_cutoff` (Anipose only), `vertical_axis` (`x`, `y`, `z`; default `z`), `flip` and `keep_skeleton` are optional. Units are converted when the file is read. IL-16 and IL-17 run on them with no water column; the 2-D metrics measure on the horizontal plane. **IL-15** runs once you give the **water column** (Surface z and Floor z on the Calibration screen); positions outside it have no depth and are counted in `frac_outside_extent`, never clipped. A native 3-D project is a 2-D project (leave Analysis type on 2D) with no Views or Fusion step; adding the first file sets Session calibration, the unit label and its confirmation, and later files must use the same target unit (`NATIVE_3D_UNIT_MISMATCH`); native and pixel sessions cannot share a project (`NATIVE_3D_MIXED`); other calibration modes are blocked (`NATIVE_3D_NEEDS_SESSION_CALIBRATION`). Not offered for native files (greyed out with a reason): every group metric, GL-16 included (a file holds one animal), and IL-3, IL-9, IL-10 and IL-14 (pixel-sized defaults that would change with the project unit). The water column is entered on the file's own vertical axis; each session's flip is applied for you. Limits: one animal per file, no z column in the per-frame table, no zones or background image, no refraction correction, a multi-animal DeepLabCut 3-D table (or one without full x, y, z triples) is still named by the scan as one it cannot read yet. The run `README.md` gains a **Native 3-D source** section. See the user guide and decision D-043.
12
13
- **3-D metrics (fused 3-D projects).** Three new metrics next to the 2-D ones, which are unchanged: **IL-16 3-D Distance Travelled** (`path_length_3d_cm`, `path_length_3d_bl`, `n_valid_steps`), **IL-17 3-D Speed** (`mean_speed_3d_cm_s`, `median_speed_3d_cm_s`, `max_speed_3d_cm_s`, `mean_speed_3d_bl_s`) and **GL-16 3-D Nearest-Neighbour Distance** (`mean_nnd_3d_cm`, `median_nnd_3d_cm`, `mean_nnd_3d_bl`, `n_skipped_frames_3d`). Positions are in cm: x and y from the top view divided by its scale, depth fraction times the tank height from the fusion settings. IL-16 and IL-17 need identities, GL-16 does not; all three compute per time bin like their 2-D counterparts. They need the top view's cm scale (scalar or session calibration): in a 2-D project they are greyed out ("needs a fused 3-D session"), under body-length calibration they are greyed out ("needs a cm scale for the top view (use scalar or session calibration)"), and a unit whose top view has no scale is skipped at run time ("needs a cm scale for the top view"), with the reason in the run README. Track2Data does not estimate the scale from the fusion. IL-17 uses the project's kinematics estimator for the vertical speed, and its horizontal part is IL-2's speed. A step, frame or speed needs a valid x, y and depth, otherwise the value is NaN, never 0. Not included: vertical speed as its own metric, 3-D inter-individual distance and cohesion. The Metrics screen presets (for example *All metrics*) no longer tick any row that is greyed out for the project (also, for instance, identity-needing metrics when every session is identity-free). `codebook.csv` lists the whole registry, so it gains rows for the three metrics in 2-D runs too; no other 2-D output changes. `track2data list-metrics` shows "fused 3-D + cm scale" for them.
13
14
- **Run a 3-D project.** A 3-D project now runs: every top/side pair with fusion settings that fuses without error becomes one run unit (id `<top>+<side>`, output folder `<run>/<top>+<side>/`), and each unit goes through the usual pipeline as a fused session. Sessions in no fusable pair, and pairs that fail to fuse, are left out with their reason: the Processing screen lists them, the run writes them to `skipped.csv` and to a "Skipped sessions" section of `PROJECT_SUMMARY.md` (both only when something was skipped), and `track2data run` prints them. A 3-D project with no fusable pair refuses to run ("no pair is ready to fuse: ..." or "Pair and fuse a top and a side session first"); one bad pair among good ones does not stop the run. Vertical position (IL-15) reads the fused depth, with `depth_extent_source` = `fusion`, and is available for a fused session whatever the project's camera view is; `frac_outside_extent` counts the side positions that fell outside the water column. Where the fused frames jump (a frame one of the views lacks), the fused track keeps a break, as a 2-D session tracked in separate intervals does, so path length and every other metric that steps from frame to frame never bridges the gap. A unit carries the TOP session's metadata (session-level columns such as `group_id`, `treatment` or `sex`), and per-animal metadata matches the fused fish by the top session's label or index. The per-frame tables (CSV long, Feather, Excel) gain `depth_fraction` and `depth_cm` for fused sessions; `sessions.csv`, each unit's README ("3-D fusion") and `manifest.json` (`run_metadata.fusion`) record how the pair was fused, including the SHA-256 of the side trajectory file. `PROJECT_SUMMARY.md` counts "Units processed (fused pairs)", and the pooled `all_sessions/manifest.json` records each unit's fusion. `track2data validate` and Validate check only the sessions that run: the consistency report reads the top session of each pair with fusion settings, and session calibration checks both sessions of such pairs. Serial and parallel runs give identical files. Processing, Preview and Export are blocked only while no pair has fusion settings; Processing shows what will run and what is skipped, and Preview shows the top-view tracks of a fused unit. `track2data validate` lists unfusable pairs as notes. 2-D projects are unchanged. Still missing: 3-D speed, path length and neighbour distance (sub-project B2); zones are one set applied to the top view; `sensitivity` refuses 3-D projects. New `Engine.run_units`, `RunPlan`, `RunUnit` and `Engine.validation_issues`.
14
15
- **Fusion of top and side views (3-D projects).** The Views page gains a **Fusion** section for the selected pair with a status line and **Set up fusion…**. The dialog shows the side view with two draggable lines for the water surface and the tank floor, fields for both rows, the tank height (default 20 cm), the shared horizontal axis (top-view x or y) with Flip, and the frame offset (hidden and fixed at 0 for "One video, two panels"), a live summary (shared frames, fused fish, positions outside the water column, agreement) and **Suggest offset**, which scans ±5 s around 0 (about 3 s on a 1-hour, 5-fish recording; needs a calibrated top view, otherwise it is disabled with a hint). The fusion keeps the fish matched in the pair on the frames both views have and adds a depth (0 = surface, 1 = floor; positions outside the column become empty and are counted). The cameras are assumed to be at right angles; the two views' horizontal positions are compared in cm and a warning shows when they disagree by more than 10% of the top-view range (needs a calibrated top view). Frame rates must match. New `FusionSettings` on each pair (`ViewPair.fusion`), `PreprocessedSession.depth`, `Engine.fuse_pair`, `fuse_all` and `suggest_offset`. The Views status warns "Fusion setup needed for …" and never blocks. A fused pair is what a 3-D run is made of (see "Run a 3-D project" above).
Copy file name to clipboardExpand all lines: docs/3d-movement/2026-10-08-3d-roadmap.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# 3-D movement: roadmap
2
2
3
-
**Status:** approved 2026-10-08. Sub-project C is in progress; E (mode switch), G, F, D (fusion) B1 (running a 3-D project) and B2 (3-D metrics) are implemented; A is not started.
3
+
**Status:** approved 2026-10-08. Sub-project C is in progress; E (mode switch), G, F, D (fusion) B1 (running a 3-D project) and B2 (3-D metrics) and A (native 3-D files) are implemented.
| F |**Panel split**: one video with the top and side views in two panels becomes two sessions (a panel rectangle per session, panel-relative coordinates). Done; see [the spec](2026-10-09-panel-split-design.md)| E |
15
15
| G |**ID correspondence**: view roles, pairing top and side sessions (regex or by hand), fish mapping between views, a Views step. Done; see [the spec](2026-10-09-id-correspondence-design.md)| E |
16
-
| A | Read 3-D tracker files (Anipose pose-3d CSV, DLC-3D). Metrics run on a chosen plane and z is stored (D-031 as written)|`feat/native-units` merged |
16
+
| A | Read 3-D tracker files (Anipose pose-3d CSV, DLC-3D). Metrics run on the horizontal plane and z is stored in the project unit. Done; see [the spec](2026-10-10-native-3d-files-design.md). **Amends D-031 a second time**|`feat/native-units` merged |
17
17
| B1 |**Run a 3-D project**: run units per fused pair, IL-15 from the fused depth, depth in the exports, UI and CLI. Done; see [the spec](2026-10-10-3d-run-design.md)| D |
18
18
| B2 | Metrics that use z: 3-D speed and path length, 3-D neighbour distance. Done; see [the spec](2026-10-10-3d-metrics-design.md). **Amends D-031**| B1 |
19
19
| D | Fuse top and side recordings into one 3-D session. Done; see [the spec](2026-10-09-fusion-design.md)| F and G (done) |
20
20
21
-
**Order: C, F/G/E, D, B1 and B2 are done; A remains.** A moves first if real 3-D files turn up. C went
21
+
**Order: all sub-projects are done.** C went
22
22
first because no data of any kind existed, it is testable on synthetic tracks, and it created the
23
23
project-level camera-view setting that B reuses.
24
24
25
25
## Hand-offs between the sub-projects
26
26
27
27
-`KeypointSelection.plane` and `camera_view` have no defined precedence. A and B must define
28
28
a vertical axis for 3-D data.
29
-
- The `has_pixel_frame` guard from native-units joins the IL-15 extent derivation when A lands.
29
+
- The `has_pixel_frame` guard from native-units joined the IL-3 and IL-14 arena fallback in A (the data extent is used, with a warning).
30
30
- Per-session camera views arrive with D (`Engine.camera_view_for(session)` is the seam).
31
31
- Whether IL-3 and IL-14, which assume a top-down view, should be gated for side views is
0 commit comments