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
fix: update default individual name from 'individual_0' to 'id_0' acr… (#618)
* fix: update default individual name from 'individual_0' to 'id_0' across codebase and tests
* docs: update input_output guide and tests/tests_units to reflect id_0 default naming
* Fix: Add fallback for missing individual in plot function; minor doc improvements
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* removed printing error message casuing error
* removed error message provided
* fix: change default individual name to 'id_0' for missing metadata
* chore: clean trailing whitespace from Makefile
* reset -W for warnings
* finishing touches
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: niksirbi <[email protected]>
|[VGG Image Annotator](via:)| VIA | .csv file for [tracks annotation](via:docs/face_track_annotation.html)| Bounding box | Load |
33
-
|[Neurodata Without Borders](https://nwb-overview.readthedocs.io/en/latest/)| NWB | .nwb file or NWBFile object with the [ndx-pose extension](https://github.com/rly/ndx-pose)| Pose | Load & Save |
34
-
| Any || Numpy arrays | Pose or Bounding box | Load & Save*|
|[VGG Image Annotator](via:)| VIA | .csv file for [tracks annotation](via:docs/face_track_annotation.html)| Bounding box | Load|
35
+
|[Neurodata Without Borders](https://nwb-overview.readthedocs.io/en/latest/)| NWB | .nwb file or NWBFile object with the [ndx-pose extension](https://github.com/rly/ndx-pose)| Pose | Load & Save|
36
+
| Any || Numpy arrays | Pose or Bounding box | Load & Save\*|
35
37
36
-
*Exporting any `movement` DataArray to a NumPy array is as simple as calling xarray's built-in {meth}`xarray.DataArray.to_numpy()` method, so no specialised "Export/Save As" function is needed, see [xarray's documentation](xarray:user-guide/duckarrays.html) for more details.
38
+
\*Exporting any `movement` DataArray to a NumPy array is as simple as calling xarray's built-in {meth}`xarray.DataArray.to_numpy()` method, so no specialised "Export/Save As" function is needed, see [xarray's documentation](xarray:user-guide/duckarrays.html) for more details.
37
39
38
40
:::{note}
39
41
Currently, `movement` only works with tracked data: either keypoints or bounding boxes whose identities are known from one frame to the next, across consecutive frames. For pose estimation, this means it only supports the predictions output by the supported software packages listed above. Loading manually labelled data—often defined over a non-continuous set of frames—is not currently supported.
40
42
:::
41
43
42
44
Below, we explain how to load pose and bounding box tracks from these supported formats, as well as how to save pose tracks back to some of them.
43
45
44
-
45
46
(target-loading-pose-tracks)=
47
+
46
48
### Loading pose tracks
47
49
48
50
The pose tracks loading functionalities are provided by the
@@ -58,6 +60,7 @@ To read a pose tracks file into a [movement poses dataset](target-poses-and-bbox
) # Optionally specify the individual name; defaults to "id_0"
122
136
123
137
# or equivalently
124
138
ds = load_poses.from_file(
125
139
"/path/to/file.analysis.csv",
126
140
source_software="Anipose",
127
141
fps=30,
128
-
individual_name="individual_0",
142
+
individual_name="id_0",
129
143
)
130
144
```
131
145
132
146
You can also directly load any pandas DataFrame `df` that's
133
147
formatted in the Anipose triangulation style:
148
+
134
149
```python
135
150
ds = load_poses.from_anipose_style_df(
136
-
df, fps=30, individual_name="individual_0"
151
+
df, fps=30, individual_name="id_0"
137
152
)
138
153
```
154
+
139
155
:::
140
156
141
157
:::{tab-item} NWB
142
158
To load NWB files in .nwb format:
159
+
143
160
```python
144
161
ds = load_poses.from_nwb_file(
145
162
"path/to/file.nwb",
@@ -157,19 +174,23 @@ ds = load_poses.from_file(
157
174
pose_estimation_key="PoseEstimation",
158
175
)
159
176
```
177
+
160
178
The above functions also accept an {class}`NWBFile<pynwb.file.NWBFile>` object as input:
179
+
161
180
```python
162
181
with pynwb.NWBHDF5IO("path/to/file.nwb", mode="r") as io:
163
182
nwb_file = io.read()
164
183
ds = load_poses.from_nwb_file(
165
184
nwb_file, pose_estimation_key="PoseEstimation"
166
185
)
167
186
```
187
+
168
188
:::
169
189
170
190
:::{tab-item} From NumPy
171
-
In the example below, we create random position data for two individuals, ``Alice`` and ``Bob``,
172
-
with three keypoints each: ``snout``, ``centre``, and ``tail_base``. These keypoints are tracked in 2D space for 100 frames, at 30 fps. The confidence scores are set to 1 for all points.
191
+
In the example below, we create random position data for two individuals, `Alice` and `Bob`,
192
+
with three keypoints each: `snout`, `centre`, and `tail_base`. These keypoints are tracked in 2D space for 100 frames, at 30 fps. The confidence scores are set to 1 for all points.
193
+
173
194
```python
174
195
import numpy as np
175
196
@@ -182,6 +203,7 @@ ds = load_poses.from_numpy(
182
203
fps=30,
183
204
)
184
205
```
206
+
185
207
:::
186
208
187
209
::::
@@ -192,9 +214,10 @@ the pose estimation software.
192
214
193
215
For more information on the poses data structure, see the [movement datasets](target-poses-and-bboxes-dataset) page.
194
216
195
-
196
217
(target-loading-bbox-tracks)=
218
+
197
219
### Loading bounding box tracks
220
+
198
221
To load bounding box tracks into a [movement bounding boxes dataset](target-poses-and-bboxes-dataset), we need the functions from the
199
222
{mod}`movement.io.load_bboxes` module, which can be imported as follows:
200
223
@@ -207,6 +230,7 @@ We currently support loading bounding box tracks in the VGG Image Annotator (VIA
Note that the x,y coordinates in the input VIA tracks .csv file represent the the top-left corner of each bounding box. Instead the corresponding ``movement`` dataset `ds` will hold in its `position` array the centroid of each bounding box.
244
+
245
+
Note that the x,y coordinates in the input VIA tracks .csv file represent the the top-left corner of each bounding box. Instead the corresponding `movement` dataset `ds` will hold in its `position` array the centroid of each bounding box.
221
246
:::
222
247
223
248
:::{tab-item} From NumPy
224
-
In the example below, we create random position data for two bounding boxes, ``id_0`` and ``id_1``,
249
+
In the example below, we create random position data for two bounding boxes, `id_0` and `id_1`,
225
250
both with the same width (40 pixels) and height (30 pixels). These are tracked in 2D space for 100 frames, which will be numbered in the resulting dataset from 0 to 99. The confidence score for all bounding boxes is set to 0.5.
251
+
226
252
```python
227
253
import numpy as np
228
254
@@ -234,6 +260,7 @@ ds = load_bboxes.from_numpy(
234
260
individual_names=["id_0", "id_1"]
235
261
)
236
262
```
263
+
237
264
:::
238
265
239
266
::::
@@ -242,8 +269,8 @@ The resulting data structure `ds` will include the centroid trajectories for eac
242
269
243
270
For more information on the bounding boxes data structure, see the [movement datasets](target-poses-and-bboxes-dataset) page.
244
271
245
-
246
272
(target-saving-pose-tracks)=
273
+
247
274
### Saving pose tracks
248
275
249
276
To export [movement poses datasets](target-poses-and-bboxes-dataset) to any of the supported third-party formats,
@@ -259,20 +286,24 @@ Depending on the desired format, use one of the following functions:
259
286
260
287
::::{tab-item} DeepLabCut
261
288
To save as a DeepLabCut file, in .h5 or .csv format:
289
+
262
290
```python
263
291
save_poses.to_dlc_file(ds, "/path/to/file.h5") # preferred format
264
292
save_poses.to_dlc_file(ds, "/path/to/file.csv")
265
293
```
294
+
266
295
The {func}`movement.io.save_poses.to_dlc_file` function also accepts
267
296
a `split_individuals` boolean argument. If set to `True`, the function will
268
297
save the data as separate single-animal DeepLabCut-style files.
To convert a `movement` poses dataset to {class}`NWBFile<pynwb.file.NWBFile>` objects:
335
+
301
336
```python
302
337
nwb_files = save_poses.to_nwb_file(ds)
303
338
```
339
+
304
340
To allow adding additional data to NWB files before saving, {func}`to_nwb_file<movement.io.save_poses.to_nwb_file>` does not write to disk directly.
305
341
Instead, it returns a list of {class}`NWBFile<pynwb.file.NWBFile>` objects---one per individual in the dataset---since NWB files are designed to represent data from a single individual.
306
342
307
343
The {func}`to_nwb_file<movement.io.save_poses.to_nwb_file>` function also accepts
308
-
a {class}`NWBFileSaveConfig<movement.io.nwb.NWBFileSaveConfig>` object as its ``config`` argument
344
+
a {class}`NWBFileSaveConfig<movement.io.nwb.NWBFileSaveConfig>` object as its `config` argument
309
345
for customising metadata such as session or subject information in the resulting NWBFiles
310
346
(see {func}`the API reference<movement.io.save_poses.to_nwb_file>` for examples).
311
347
312
348
These {class}`NWBFile<pynwb.file.NWBFile>` objects can then be saved to disk as .nwb files using {class}`pynwb.NWBHDF5IO`:
349
+
313
350
```python
314
351
from pynwb importNWBHDF5IO
315
352
316
353
forfilein nwb_files:
317
354
with NWBHDF5IO(f"{file.identifier}.nwb", "w") as io:
318
355
io.write(file)
319
356
```
357
+
320
358
::::
321
359
322
360
:::::
323
361
324
-
325
362
(target-saving-bboxes-tracks)=
363
+
326
364
### Saving bounding box tracks
327
365
328
366
We currently do not provide explicit methods to export a movement bounding boxes dataset in a specific format. However, you can save the bounding box tracks to a .csv file using the standard Python library `csv`.
@@ -349,9 +387,11 @@ with open(filepath, mode="w", newline="") as file:
349
387
writer.writerow([frame, individual, x, y, width, height, confidence])
350
388
351
389
```
390
+
352
391
Alternatively, we can convert the `movement` bounding boxes dataset to a pandas DataFrame with the {meth}`xarray.DataArray.to_dataframe` method, wrangle the dataframe as required, and then apply the {meth}`pandas.DataFrame.to_csv` method to save the data as a .csv file.
353
392
354
393
(target-netcdf)=
394
+
355
395
## Native saving and loading with netCDF
356
396
357
397
Because `movement` datasets are {class}`xarray.Dataset` objects, we can rely on
@@ -367,7 +407,7 @@ To save any xarray dataset `ds` to a netCDF file:
0 commit comments