|
| 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. |
0 commit comments