Add a dismissable welcome modal that walks first-time users through the proper annotation sequence (slider to end → check open ROIs → slider to start → arrow-key fine-tune → click). Stays hidden after the first "Got it" via localStorage; the ? button in the header reopens it any time. Picker keyboard shortcuts are inert while the modal is showing. Container exposes 8085 instead of 8000 (8000 was free, but Giorgio's preferred 8082 is already in use on this host; 8085 is the closest free port). Internal port stays 8000 so the FastAPI app is unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
70 lines
2.3 KiB
Markdown
70 lines
2.3 KiB
Markdown
# Cupido — web-based barrier-opening picker
|
|
|
|
A small FastAPI + HTML5-video app for annotating the barrier-opening
|
|
moment in each tracked recording. Lives in its own Docker container so
|
|
it can run on the lab server without polluting any existing
|
|
environment.
|
|
|
|
## What it does
|
|
|
|
For every video referenced by `all_video_info_merged.tsv` that has a
|
|
tracking DB on disk and isn't yet in `barrier_opening.csv`, it serves
|
|
a `<video>` element pre-loaded with that mp4. The analyst plays /
|
|
scrubs / pauses at the moment the barrier opens, then clicks one of:
|
|
|
|
| button | meaning | written to `bad_rois` |
|
|
|---|---|---|
|
|
| **All barriers open** | every ROI (1..6) is usable post-opening | _empty_ |
|
|
| **Upper barriers open** | only the top row opens (ROIs 1, 3, 5) | `2,4,6` |
|
|
| **Lower barriers open** | only the bottom row opens (ROIs 2, 4, 6) | `1,3,5` |
|
|
|
|
Plus a **Skip** (advance without saving) and **Unusable** (write
|
|
`opening_s = NaN`).
|
|
|
|
## Keyboard shortcuts
|
|
|
|
- <kbd>Space</kbd> — play / pause
|
|
- <kbd>←</kbd> / <kbd>→</kbd> — ±5 s
|
|
- <kbd>Shift</kbd>+arrows — ±1 s
|
|
- <kbd>Ctrl</kbd>+arrows — ±0.1 s
|
|
- <kbd>,</kbd> / <kbd>.</kbd> — ±1 frame
|
|
- <kbd>1</kbd> / <kbd>2</kbd> / <kbd>3</kbd> — All / Upper / Lower
|
|
- <kbd>s</kbd> — skip ; <kbd>u</kbd> — unusable
|
|
|
|
## Run locally (docker compose)
|
|
|
|
```bash
|
|
cd scripts/barrier_picker_app
|
|
docker compose up --build
|
|
```
|
|
|
|
Then browse to http://localhost:8085/.
|
|
|
|
The container mounts:
|
|
- `/mnt/data/projects/cupido` (data volume, read-only)
|
|
- `/mnt/ethoscope_data/videos` (source mp4s, read-only)
|
|
- `data/metadata/` from the repo (read-write — for persisting
|
|
`barrier_opening.csv`)
|
|
|
|
Adjust paths in `docker-compose.yml` if your layout differs.
|
|
|
|
## Run without Docker (development)
|
|
|
|
```bash
|
|
cd scripts/barrier_picker_app
|
|
pip install -r requirements.txt
|
|
python app.py # serves on http://localhost:8000
|
|
```
|
|
|
|
By default it expects:
|
|
- merged TSV at `/mnt/data/projects/cupido/all_video_info_merged.tsv`
|
|
- inventory at `/cupido/data/metadata/video_inventory.csv`
|
|
- writes to `/cupido/data/metadata/barrier_opening.csv`
|
|
|
|
Override via environment variables:
|
|
```bash
|
|
CUPIDO_DATA_VOLUME=/path/to/data \
|
|
CUPIDO_INVENTORY_CSV=$(pwd)/../../data/metadata/video_inventory.csv \
|
|
CUPIDO_OUTPUT_CSV=$(pwd)/../../data/metadata/barrier_opening.csv \
|
|
python app.py
|
|
```
|