Skip to content

Commit 8f6162a

Browse files
committed
add guide on organizing projects
1 parent 59c6752 commit 8f6162a

3 files changed

Lines changed: 195 additions & 0 deletions

File tree

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
Organizing your Cheese3D projects/data
2+
======================================
3+
4+
A Cheese3D project is just a directory on disk: a configuration file, some video data, optionally an ephys recording, and a pose estimation model. This basic structure offers an easy way to keep projects self-contained and organized. This guide describes the recommended layout and the conventions Cheese3D uses to locate files inside it.
5+
6+
.. contents::
7+
:local:
8+
:depth: 2
9+
:backlinks: none
10+
11+
Anatomy of a project folder
12+
---------------------------
13+
14+
A Cheese3D project is self-contained in a single folder whose name matches the ``name`` field in :ref:`main_config_ref`. A fully populated project looks like this:
15+
16+
.. code-block:: text
17+
18+
<project>/
19+
|__ config.yaml # All project settings (see Configuration reference)
20+
|__ videos/ # Source video recordings, one sub-folder per session
21+
| |__ <session-1>/
22+
| | |__ <video files>
23+
| |__ <session-2>/
24+
| |__ <video files>
25+
|__ ephys/ # Optional; only when ephys_root is set
26+
| |__ <session-1>/
27+
| |__ <ephys files>
28+
|__ model/ # 2D pose estimation models for this project
29+
| |__ <model-name>/
30+
| |__ backend/ # The underlying DLC project
31+
| |__ labels/ # Frames extracted/labeled in this project
32+
|__ triangulation/ # Auto-created during the 3D stage
33+
|__ config.toml # Anipose configuration
34+
|__ <session-1>/
35+
|__ videos-raw/ # Synchronized inputs (symlinks to videos/)
36+
|__ calibration/ # Camera calibration output
37+
|__ pose-2d/ # 2D keypoint predictions
38+
|__ pose-3d/ # 3D triangulated keypoints
39+
|__ cheese3d/ # Cheese3D feature CSV
40+
|__ videos-compare/ # Labeled output videos
41+
42+
Only ``config.yaml`` is required up front. Every other folder is either populated by you (e.g., ``videos``, ``ephys``) or created by Cheese3D as you advance through the pipeline (e.g., the ``triangulation/`` folder).
43+
44+
The names ``videos``, ``ephys``, ``model``, and ``triangulation`` are defaults; they can be remapped via the ``video_root``, ``ephys_root``, and ``model_root`` keys in :ref:`main_config_ref`. The discussion below uses the default names.
45+
46+
Organizing source video recordings
47+
----------------------------------
48+
49+
Cheese3D treats each recording session as a folder of videos---typically one file per camera view---under ``videos/``. The folder name is the **session name**, which you list under ``sessions`` in :ref:`main_config_ref`:
50+
51+
.. code-block:: text
52+
53+
videos/
54+
|__ 20231031_chew/
55+
| |__ chewing_TL_001.avi
56+
| |__ chewing_TR_001.avi
57+
| |__ chewing_BC_001.avi
58+
| |__ ...
59+
|__ 20231101_baseline/
60+
|__ baseline_TL_001.avi
61+
|__ ...
62+
63+
Within each session folder, Cheese3D discovers individual videos using the ``video_regex`` pattern. The regex must capture at least a ``view`` group (so each file is matched to a camera) and may include other groups like ``type`` for further grouping and filtering.
64+
65+
Naming video files
66+
^^^^^^^^^^^^^^^^^^
67+
68+
The video filename is what Cheese3D uses to attach a camera view and other information to a recording. The more metadata you encode in the filename, the more flexibility you have later when filtering or grouping recordings via ``video_regex``.
69+
70+
A useful filename scheme typically encodes:
71+
72+
* **view** (required): which camera the video came from (e.g. ``TL``, ``TR``, ``BC``). Must match the ``view`` field of an entry in :ref:`reference/configuration:View options`.
73+
* **type**: the kind of recording (e.g. ``cal`` for calibration, ``behavior`` for experimental trials).
74+
* **subject**: the mouse identifier (e.g. ``mouse1``, ``M042``). Encoding this lets you keep many subjects' recordings in one folder and split them apart via configuration.
75+
* **condition**: an experimental condition or stimulus label (e.g. ``baseline``, ``stim``).
76+
* **session number** or **repetition**: a counter to disambiguate repeated recordings.
77+
78+
For example, a recording folder with two subjects across baseline and stim conditions might look like:
79+
80+
.. code-block:: text
81+
82+
videos/
83+
|__ 20240115_pilot/
84+
|__ mouse1_cal_TL_001.avi
85+
|__ mouse1_cal_TR_001.avi
86+
|__ ...
87+
|__ mouse1_baseline_TL_001.avi
88+
|__ mouse1_baseline_TR_001.avi
89+
|__ ...
90+
|__ mouse2_stim_TL_001.avi
91+
|__ mouse2_stim_TR_001.avi
92+
|__ ...
93+
94+
You can describe this layout with a regex that captures each piece of metadata as a named group:
95+
96+
.. code-block:: yaml
97+
98+
video_regex:
99+
_path_: "{{subject}}_{{type}}_{{view}}_{{rep}}\\.avi"
100+
subject: "mouse\\d+"
101+
type: "cal|baseline|stim"
102+
view: "TL|TR|L|R|TC|BC"
103+
rep: "\\d+"
104+
105+
Any group you define here becomes a key you can filter on in ``sessions`` and ``calibration``. For example, to only use specific subjects from a folder for analysis:
106+
107+
.. code-block:: yaml
108+
109+
sessions:
110+
- name: 20240115_pilot
111+
subject: mouse1
112+
type: baseline
113+
- name: 20240115_pilot
114+
subject: mouse2
115+
type: stim
116+
calibration:
117+
type: cal
118+
119+
In this configuration, calibration videos are shared across subjects (since they only filter on ``type: cal``), while each session pulls only the trials belonging to one mouse. See :doc:`/howto/regex` for a complete walkthrough of how the dictionary form is translated into a Python regex with named groups.
120+
121+
.. tip::
122+
123+
Pick a filename convention before you start recording and stick to it. The ``video_regex`` only needs to be written once if every recording follows the same scheme. Renaming files after the fact is tedious; baking subject IDs, conditions, and view codes into your acquisition pipeline pays off later.
124+
125+
Organizing ephys data
126+
---------------------
127+
128+
Ephys is optional. To use it, set ``ephys_root`` in :ref:`main_config_ref` (commonly to ``ephys``) and add an ``ephys_param`` block for your acquisition system. Cheese3D currently supports `Allego <https://www.neuronexus.com/products/software/radiens/>`__, `Open Ephys <https://open-ephys.org/gui>`__, and `DSI <https://www.datasci.com/products/software/ponemah>`__ --- see :ref:`reference/configuration:Ephys options`.
129+
130+
Ephys files are organized **per session, mirroring the video layout**. Cheese3D looks for ephys recordings under ``<ephys_root>/<session-name>/``, matching the same session names listed in ``sessions``:
131+
132+
.. code-block:: text
133+
134+
ephys/
135+
|__ 20231031_chew/
136+
| |__ <ephys recording files>
137+
|__ 20231101_baseline/
138+
|__ <ephys recording files>
139+
140+
Which files Cheese3D picks up inside each session folder is controlled by the ``ephys_regex`` pattern, just like videos. After running ``cheese3d sync``, a sibling ``.align.json`` file is written next to each ephys recording with the alignment parameters (see :doc:`/howto/sync`).
141+
142+
Pose estimation models
143+
----------------------
144+
145+
The 2D pose estimation model lives under ``model/<model-name>/``, where ``<model-name>`` is the ``model.name`` field in :ref:`main_config_ref`:
146+
147+
.. code-block:: text
148+
149+
model/
150+
|__ cheese3d_demo_model/
151+
|__ backend/ # The DLC project (config.yaml, training-datasets/, etc.)
152+
|__ labels/ # Frames extracted and labeled inside Cheese3D
153+
154+
You can either **create** a fresh model when setting up a new project or **import** an existing DLC project that you've already trained (the interactive UI prompts for either). Importing is the right choice when:
155+
156+
* you have a pre-trained model that already covers the keypoints you care about, or
157+
* multiple projects share the same keypoint schema and you'd rather not retrain.
158+
159+
Importing copies the DLC project into ``model/<model-name>/backend/``, so each Cheese3D project gets its own independent copy. If you want a single canonical model to be the source of truth, keep the model outside Cheese3D (e.g. in a shared ``dlc-projects/`` directory) and either:
160+
161+
* re-import them into each project, keeping independent copies, or
162+
* change the ``model_root`` key in :ref:`main_config_ref` to point to the shared DLC project folder.
163+
164+
.. tip::
165+
166+
Newly labeled frames go into ``model/<model-name>/labels/`` and are automatically kept in sync with the backend folder.
167+
168+
The ``triangulation/`` folder
169+
-----------------------------
170+
171+
The ``triangulation`` folder contains an `Anipose <https://github.com/lambdaloop/anipose>`__ project with one sub-folder per session, plus a top-level ``config.toml`` that Cheese3D generates from your ``config.yaml``. Everything in this folder is generated.
172+
173+
Managing multiple projects
174+
--------------------------
175+
176+
Each Cheese3D project is independent. If you run several experiments, give each one its own project folder rather than packing them together. A common workspace layout looks like:
177+
178+
.. code-block:: text
179+
180+
cheese3d-workspace/
181+
|__ dlc-projects/ # Shared DLC models, used by projects below
182+
| |__ mymodel/
183+
|__ 20231031_chewing_study/
184+
| |__ config.yaml
185+
| |__ videos/
186+
|__ 20240115_baseline_pilot/
187+
|__ config.yaml
188+
|__ videos/
189+
190+
Putting all projects under a single parent directory makes it easy to back up everything at once, browse past experiments, and share models between them. Similar to sharing DLC models, you can also share video or ephys data by using a shared folder and adjusting ``video_root`` and ``ephys_root`` in the config.

docs/source/guides/quick-start.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ A Cheese3D project (by default) is self-contained in a folder with the same name
5151

5252
Store all your Cheese3D projects in a single directory to keep them organized in one place!
5353

54+
.. seealso::
55+
56+
For a deeper look at the project layout --- including how videos and ephys files are organized per session, how to share models between projects, and how to back projects up --- see :doc:`/guides/organizing-projects`.
57+
5458
.. _create_new_project:
5559
Creating a new project
5660
----------------------

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ If you use Cheese3D, please cite our paper:
4646

4747
guides/installation
4848
guides/quick-start
49+
guides/organizing-projects
4950
guides/hardware
5051

5152
.. toctree::

0 commit comments

Comments
 (0)