diff --git a/.buildinfo b/.buildinfo index 8691d3ba..1e9bfcec 100644 --- a/.buildinfo +++ b/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 57450292a03088d8c741a2d3ad9251c2 +config: 73eb998e14fd2132a732d009e358aee8 tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.doctrees/api/movement.io.load_poses.from_dlc_file.doctree b/.doctrees/api/movement.io.load_poses.from_dlc_file.doctree index 53ae6402..409f4c9e 100644 Binary files a/.doctrees/api/movement.io.load_poses.from_dlc_file.doctree and b/.doctrees/api/movement.io.load_poses.from_dlc_file.doctree differ diff --git a/.doctrees/api/movement.io.load_poses.from_lp_file.doctree b/.doctrees/api/movement.io.load_poses.from_lp_file.doctree new file mode 100644 index 00000000..40ccd221 Binary files /dev/null and b/.doctrees/api/movement.io.load_poses.from_lp_file.doctree differ diff --git a/.doctrees/api/movement.io.load_poses.from_sleap_file.doctree b/.doctrees/api/movement.io.load_poses.from_sleap_file.doctree index 657c58f9..3b39851f 100644 Binary files a/.doctrees/api/movement.io.load_poses.from_sleap_file.doctree and b/.doctrees/api/movement.io.load_poses.from_sleap_file.doctree differ diff --git a/.doctrees/api/movement.io.save_poses.to_dlc_file.doctree b/.doctrees/api/movement.io.save_poses.to_dlc_file.doctree index 31ce75be..b973f93d 100644 Binary files a/.doctrees/api/movement.io.save_poses.to_dlc_file.doctree and b/.doctrees/api/movement.io.save_poses.to_dlc_file.doctree differ diff --git a/.doctrees/api/movement.io.save_poses.to_lp_file.doctree b/.doctrees/api/movement.io.save_poses.to_lp_file.doctree new file mode 100644 index 00000000..a975cd98 Binary files /dev/null and b/.doctrees/api/movement.io.save_poses.to_lp_file.doctree differ diff --git a/.doctrees/api/movement.io.save_poses.to_sleap_analysis_file.doctree b/.doctrees/api/movement.io.save_poses.to_sleap_analysis_file.doctree new file mode 100644 index 00000000..ef23839d Binary files /dev/null and b/.doctrees/api/movement.io.save_poses.to_sleap_analysis_file.doctree differ diff --git a/.doctrees/api/movement.io.validators.ValidPoseTracks.doctree b/.doctrees/api/movement.io.validators.ValidPoseTracks.doctree index a0a82a3c..951d7d52 100644 Binary files a/.doctrees/api/movement.io.validators.ValidPoseTracks.doctree and b/.doctrees/api/movement.io.validators.ValidPoseTracks.doctree differ diff --git a/.doctrees/api_index.doctree b/.doctrees/api_index.doctree index 8fab8ca5..c613bca8 100644 Binary files a/.doctrees/api_index.doctree and b/.doctrees/api_index.doctree differ diff --git a/.doctrees/community/contributing.doctree b/.doctrees/community/contributing.doctree index c2b6e377..c3c25085 100644 Binary files a/.doctrees/community/contributing.doctree and b/.doctrees/community/contributing.doctree differ diff --git a/.doctrees/community/index.doctree b/.doctrees/community/index.doctree index 582f378a..8f3fc40f 100644 Binary files a/.doctrees/community/index.doctree and b/.doctrees/community/index.doctree differ diff --git a/.doctrees/community/mission-scope.doctree b/.doctrees/community/mission-scope.doctree index bf269e8e..05a9d856 100644 Binary files a/.doctrees/community/mission-scope.doctree and b/.doctrees/community/mission-scope.doctree differ diff --git a/.doctrees/community/roadmap.doctree b/.doctrees/community/roadmap.doctree index 0505d794..4915cf34 100644 Binary files a/.doctrees/community/roadmap.doctree and b/.doctrees/community/roadmap.doctree differ diff --git a/.doctrees/environment.pickle b/.doctrees/environment.pickle index 3a1ca679..d07dbcff 100644 Binary files a/.doctrees/environment.pickle and b/.doctrees/environment.pickle differ diff --git a/.doctrees/examples/load_and_explore_poses.doctree b/.doctrees/examples/load_and_explore_poses.doctree index ba08f975..4098b950 100644 Binary files a/.doctrees/examples/load_and_explore_poses.doctree and b/.doctrees/examples/load_and_explore_poses.doctree differ diff --git a/.doctrees/examples/sg_execution_times.doctree b/.doctrees/examples/sg_execution_times.doctree index 67e3d544..2cd8d1b1 100644 Binary files a/.doctrees/examples/sg_execution_times.doctree and b/.doctrees/examples/sg_execution_times.doctree differ diff --git a/.doctrees/getting_started.doctree b/.doctrees/getting_started.doctree index e0652d7f..9c0d2c0b 100644 Binary files a/.doctrees/getting_started.doctree and b/.doctrees/getting_started.doctree differ diff --git a/.doctrees/index.doctree b/.doctrees/index.doctree index 9fd4d16c..e0c04900 100644 Binary files a/.doctrees/index.doctree and b/.doctrees/index.doctree differ diff --git a/.doctrees/sg_execution_times.doctree b/.doctrees/sg_execution_times.doctree index 5b3d1b4a..138638f4 100644 Binary files a/.doctrees/sg_execution_times.doctree and b/.doctrees/sg_execution_times.doctree differ diff --git a/.doctrees/snippets/get-in-touch.doctree b/.doctrees/snippets/get-in-touch.doctree index bc5b8c04..bd483f98 100644 Binary files a/.doctrees/snippets/get-in-touch.doctree and b/.doctrees/snippets/get-in-touch.doctree differ diff --git a/.doctrees/snippets/status-warning.doctree b/.doctrees/snippets/status-warning.doctree index 0a91609e..62cb3693 100644 Binary files a/.doctrees/snippets/status-warning.doctree and b/.doctrees/snippets/status-warning.doctree differ diff --git a/_downloads/307bfbce3b04c474f9b3bd90e970e4c9/load_and_explore_poses.py b/_downloads/307bfbce3b04c474f9b3bd90e970e4c9/load_and_explore_poses.py index 8562b532..de5f5196 100644 --- a/_downloads/307bfbce3b04c474f9b3bd90e970e4c9/load_and_explore_poses.py +++ b/_downloads/307bfbce3b04c474f9b3bd90e970e4c9/load_and_explore_poses.py @@ -38,7 +38,7 @@ # %% # The loaded dataset contains two data variables: -# ``pose_tracks`` and ``confidence``` +# ``pose_tracks`` and ``confidence``. # To get the pose tracks: pose_tracks = ds.pose_tracks diff --git a/_downloads/7f0c10d5c8b88801f34de1b2292ae010/load_and_explore_poses.ipynb b/_downloads/7f0c10d5c8b88801f34de1b2292ae010/load_and_explore_poses.ipynb index ce7838b9..ccc14ec3 100644 --- a/_downloads/7f0c10d5c8b88801f34de1b2292ae010/load_and_explore_poses.ipynb +++ b/_downloads/7f0c10d5c8b88801f34de1b2292ae010/load_and_explore_poses.ipynb @@ -83,7 +83,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The loaded dataset contains two data variables:\n``pose_tracks`` and ``confidence```\nTo get the pose tracks:\n\n" + "The loaded dataset contains two data variables:\n``pose_tracks`` and ``confidence``.\nTo get the pose tracks:\n\n" ] }, { @@ -186,7 +186,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.6" + "version": "3.11.7" } }, "nbformat": 4, diff --git a/_downloads/bc82bea3a5dd7bdba60b65220891d9e5/examples_python.zip b/_downloads/bc82bea3a5dd7bdba60b65220891d9e5/examples_python.zip index 8c336851..0b2f10d6 100644 Binary files a/_downloads/bc82bea3a5dd7bdba60b65220891d9e5/examples_python.zip and b/_downloads/bc82bea3a5dd7bdba60b65220891d9e5/examples_python.zip differ diff --git a/_downloads/fb625db3c50d423b1b7881136ffdeec8/examples_jupyter.zip b/_downloads/fb625db3c50d423b1b7881136ffdeec8/examples_jupyter.zip index 84175a66..31503bce 100644 Binary files a/_downloads/fb625db3c50d423b1b7881136ffdeec8/examples_jupyter.zip and b/_downloads/fb625db3c50d423b1b7881136ffdeec8/examples_jupyter.zip differ diff --git a/_images/dataset_structure.png b/_images/dataset_structure.png new file mode 100644 index 00000000..36bc595d Binary files /dev/null and b/_images/dataset_structure.png differ diff --git a/_images/movement_overview.png b/_images/movement_overview.png new file mode 100644 index 00000000..8af12daa Binary files /dev/null and b/_images/movement_overview.png differ diff --git a/_modules/index.html b/_modules/index.html index bfe0d001..34b36d67 100644 --- a/_modules/index.html +++ b/_modules/index.html @@ -27,6 +27,7 @@ + @@ -39,13 +40,14 @@ - + + @@ -121,7 +123,7 @@ -

movement v0.0.11

+

movement v0.0.12

@@ -217,6 +219,18 @@ GitHub + @@ -327,6 +341,18 @@ GitHub + @@ -425,23 +451,15 @@

All modules for which code is available

@@ -449,10 +467,24 @@

All modules for which code is available

diff --git a/_modules/movement/datasets.html b/_modules/movement/datasets.html index 081372e6..88b304b6 100644 --- a/_modules/movement/datasets.html +++ b/_modules/movement/datasets.html @@ -27,6 +27,7 @@ + @@ -39,13 +40,14 @@ - + + @@ -121,7 +123,7 @@ -

movement v0.0.11

+

movement v0.0.12

@@ -217,6 +219,18 @@ GitHub + @@ -327,6 +341,18 @@ GitHub + @@ -497,23 +523,15 @@

Source code for movement.datasets

   
     
   
@@ -521,10 +539,24 @@ 

Source code for movement.datasets

   
     
   
diff --git a/_modules/movement/io/load_poses.html b/_modules/movement/io/load_poses.html
index 8bd10271..0d7b3e93 100644
--- a/_modules/movement/io/load_poses.html
+++ b/_modules/movement/io/load_poses.html
@@ -27,6 +27,7 @@
 
 
 
+    
     
     
     
@@ -39,13 +40,14 @@
 
   
 
-    
+    
     
     
     
     
     
     
+    
     
     
   
@@ -121,7 +123,7 @@
   
   
   
-    

movement v0.0.11

+

movement v0.0.12

@@ -217,6 +219,18 @@ GitHub +
@@ -327,6 +341,18 @@ GitHub + @@ -388,7 +414,7 @@

Source code for movement.io.load_poses

 import logging
 from pathlib import Path
-from typing import Optional, Union
+from typing import Literal, Optional, Union
 
 import h5py
 import numpy as np
@@ -476,8 +502,8 @@ 

Source code for movement.io.load_poses

     Parameters
     ----------
     file_path : pathlib.Path or str
-        Path to the file containing the SLEAP predictions in ".h5"
-        (analysis) format. Alternatively, an ".slp" (labels) file can
+        Path to the file containing the SLEAP predictions in .h5
+        (analysis) format. Alternatively, a .slp (labels) file can
         also be supplied (but this feature is experimental, see Notes).
     fps : float, optional
         The number of frames per second in the video. If None (default),
@@ -490,18 +516,18 @@ 

Source code for movement.io.load_poses

 
     Notes
     -----
-    The SLEAP predictions are normally saved in ".slp" files, e.g.
+    The SLEAP predictions are normally saved in .slp files, e.g.
     "v1.predictions.slp". An analysis file, suffixed with ".h5" can be exported
-    from the ".slp" file, using either the command line tool `sleap-convert`
+    from the .slp file, using either the command line tool `sleap-convert`
     (with the "--format analysis" option enabled) or the SLEAP GUI (Choose
     "Export Analysis HDF5…" from the "File" menu) [1]_. This is the
     preferred format for loading pose tracks from SLEAP into *movement*.
 
-    You can also directly load the ".slp" file. However, if the file contains
+    You can also directly load the .slp file. However, if the file contains
     multiple videos, only the pose tracks from the first video will be loaded.
     If the file contains a mix of user-labelled and predicted instances, user
     labels are prioritised over predicted instances to mirror SLEAP's approach
-    when exporting ".h5" analysis files [2]_.
+    when exporting .h5 analysis files [2]_.
 
     *movement* expects the tracks to be assigned and proofread before loading
     them, meaning each track is interpreted as a single individual/animal. If
@@ -548,6 +574,36 @@ 

Source code for movement.io.load_poses

     return ds
+
[docs]def from_lp_file( + file_path: Union[Path, str], fps: Optional[float] = None +) -> xr.Dataset: + """Load pose tracking data from a LightningPose (LP) output file + into an xarray Dataset. + + Parameters + ---------- + file_path : pathlib.Path or str + Path to the file containing the LP predicted poses, in .csv format. + fps : float, optional + The number of frames per second in the video. If None (default), + the `time` coordinates will be in frame numbers. + + Returns + ------- + xarray.Dataset + Dataset containing the pose tracks, confidence scores, and metadata. + + Examples + -------- + >>> from movement.io import load_poses + >>> ds = load_poses.from_lp_file("path/to/file.csv", fps=30) + """ + + return _from_lp_or_dlc_file( + file_path=file_path, source_software="LightningPose", fps=fps + )
+ +
[docs]def from_dlc_file( file_path: Union[Path, str], fps: Optional[float] = None ) -> xr.Dataset: @@ -557,8 +613,8 @@

Source code for movement.io.load_poses

     Parameters
     ----------
     file_path : pathlib.Path or str
-        Path to the file containing the DLC predicted poses, either in ".h5"
-        or ".csv" format.
+        Path to the file containing the DLC predicted poses, either in .h5
+        or .csv format.
     fps : float, optional
         The number of frames per second in the video. If None (default),
         the `time` coordinates will be in frame numbers.
@@ -578,10 +634,41 @@ 

Source code for movement.io.load_poses

     >>> ds = load_poses.from_dlc_file("path/to/file.h5", fps=30)
     """
 
+    return _from_lp_or_dlc_file(
+        file_path=file_path, source_software="DeepLabCut", fps=fps
+    )
+ + +def _from_lp_or_dlc_file( + file_path: Union[Path, str], + source_software: Literal["LightningPose", "DeepLabCut"], + fps: Optional[float] = None, +) -> xr.Dataset: + """Loads pose tracking data from a DeepLabCut (DLC) or + a LightningPose (LP) output file into an xarray Dataset. + + Parameters + ---------- + file_path : pathlib.Path or str + Path to the file containing the DLC predicted poses, either in .h5 + or .csv format. + source_software : {'LightningPose', 'DeepLabCut'} + fps : float, optional + The number of frames per second in the video. If None (default), + the `time` coordinates will be in frame numbers. + + Returns + ------- + xarray.Dataset + Dataset containing the pose tracks, confidence scores, and metadata. + """ + + expected_suffix = [".csv"] + if source_software == "DeepLabCut": + expected_suffix.append(".h5") + file = ValidFile( - file_path, - expected_permission="r", - expected_suffix=[".csv", ".h5"], + file_path, expected_permission="r", expected_suffix=expected_suffix ) # Load the DLC poses into a DataFrame @@ -595,12 +682,18 @@

Source code for movement.io.load_poses

     ds = from_dlc_df(df=df, fps=fps)
 
     # Add metadata as attrs
-    ds.attrs["source_software"] = "DeepLabCut"
+    ds.attrs["source_software"] = source_software
     ds.attrs["source_file"] = file.path.as_posix()
 
+    # If source_software="LightningPose", we need to re-validate (because the
+    # validation call in from_dlc_df was run with source_software="DeepLabCut")
+    # This rerun enforces a single individual for LightningPose datasets.
+    if source_software == "LightningPose":
+        ds.poses.validate()
+
     logger.info(f"Loaded pose tracks from {file.path}:")
     logger.info(ds)
-    return ds
+ return ds def _load_from_sleap_analysis_file( @@ -647,6 +740,7 @@

Source code for movement.io.load_poses

             individual_names=individual_names,
             keypoint_names=[n.decode() for n in f["node_names"][:]],
             fps=fps,
+            source_software="SLEAP",
         )
 
 
@@ -686,6 +780,7 @@ 

Source code for movement.io.load_poses

         individual_names=individual_names,
         keypoint_names=[kp.name for kp in labels.skeletons[0].nodes],
         fps=fps,
+        source_software="SLEAP",
     )
 
 
@@ -708,7 +803,7 @@ 

Source code for movement.io.load_poses

     This function only considers SLEAP instances in the first
     video of the SLEAP `Labels` object. User-labelled instances are
     prioritised over predicted instances, mirroring SLEAP's approach
-    when exporting ".h5" analysis files [1]_.
+    when exporting .h5 analysis files [1]_.
 
     This function is adapted from `Labels.numpy()` from the
     `sleap_io` package [2]_.
@@ -906,23 +1001,15 @@ 

Source code for movement.io.load_poses

   
     
   
@@ -930,10 +1017,24 @@ 

Source code for movement.io.load_poses

   
     
   
diff --git a/_modules/movement/io/save_poses.html b/_modules/movement/io/save_poses.html
index 3ea32047..b0abaa19 100644
--- a/_modules/movement/io/save_poses.html
+++ b/_modules/movement/io/save_poses.html
@@ -27,6 +27,7 @@
 
 
 
+    
     
     
     
@@ -39,13 +40,14 @@
 
   
 
-    
+    
     
     
     
     
     
     
+    
     
     
   
@@ -121,7 +123,7 @@
   
   
   
-    

movement v0.0.11

+

movement v0.0.12

@@ -217,6 +219,18 @@ GitHub +
@@ -327,6 +341,18 @@ GitHub +
@@ -390,6 +416,7 @@

Source code for movement.io.save_poses

 from pathlib import Path
 from typing import Literal, Union
 
+import h5py
 import numpy as np
 import pandas as pd
 import xarray as xr
@@ -500,13 +527,8 @@ 

Source code for movement.io.save_poses

     to_dlc_file : Save the xarray dataset containing pose tracks directly
         to a DeepLabCut-style .h5 or .csv file.
     """
-    if not isinstance(ds, xr.Dataset):
-        raise log_error(
-            ValueError, f"Expected an xarray Dataset, but got {type(ds)}."
-        )
-
-    ds.poses.validate()  # validate the dataset
 
+    _validate_dataset(ds)
     scorer = ["movement"]
     bodyparts = ds.coords["keypoints"].data.tolist()
     coords = ds.coords["space"].data.tolist() + ["likelihood"]
@@ -558,17 +580,18 @@ 

Source code for movement.io.save_poses

     file_path : pathlib.Path or str
         Path to the file to save the DLC poses to. The file extension
         must be either .h5 (recommended) or .csv.
-    split_individuals : bool, optional
+    split_individuals : bool or "auto", optional
+        Whether to save individuals to separate files or to the same file.\n
         If True, each individual will be saved to a separate file,
         formatted as in a single-animal DeepLabCut project - i.e. without
         the "individuals" column level. The individual's name will be appended
         to the file path, just before the file extension, i.e.
-        "/path/to/filename_individual1.h5".
+        "/path/to/filename_individual1.h5".\n
         If False, all individuals will be saved to the same file,
         formatted as in a multi-animal DeepLabCut project - i.e. the columns
         will include the "individuals" level. The file path will not be
-        modified.
-        If "auto" the argument's value be determined based on the number of
+        modified.\n
+        If "auto" the argument's value is determined based on the number of
         individuals in the dataset: True if there is only one, and
         False if there are more than one. This is the default.
 
@@ -581,19 +604,11 @@ 

Source code for movement.io.save_poses

     Examples
     --------
     >>> from movement.io import save_poses, load_poses
-    >>> ds = load_poses.from_sleap("/path/to/file_sleap.analysis.h5")
+    >>> ds = load_poses.from_sleap_file("/path/to/file_sleap.analysis.h5")
     >>> save_poses.to_dlc_file(ds, "/path/to/file_dlc.h5")
     """
 
-    try:
-        file = ValidFile(
-            file_path,
-            expected_permission="w",
-            expected_suffix=[".csv", ".h5"],
-        )
-    except (OSError, ValueError) as error:
-        logger.error(error)
-        raise error
+    file = _validate_file_path(file_path, expected_suffix=[".csv", ".h5"])
 
     # Sets default behaviour for the function
     if split_individuals == "auto":
@@ -624,6 +639,219 @@ 

Source code for movement.io.save_poses

         if isinstance(df_all, pd.DataFrame):
             _save_dlc_df(file.path, df_all)
         logger.info(f"Saved PoseTracks dataset to {file.path}.")
+ + +
[docs]def to_lp_file( + ds: xr.Dataset, + file_path: Union[str, Path], +) -> None: + """Save the xarray dataset containing pose tracks to a LightningPose-style + .csv file. See Notes for more details. + + Parameters + ---------- + ds : xarray.Dataset + Dataset containing pose tracks, confidence scores, and metadata. + file_path : pathlib.Path or str + Path to the .csv file to save the poses to. + + Notes + ----- + LightningPose saves pose estimation outputs as .csv files, using the same + format as single-animal DeepLabCut projects. Therefore, under the hood, + this function calls ``to_dlc_file`` with ``split_individuals=True``. This + setting means that each individual is saved to a separate file, with + the individual's name appended to the file path, just before the file + extension, i.e. "/path/to/filename_individual1.csv". + + See Also + -------- + to_dlc_file : Save the xarray dataset containing pose tracks to a + DeepLabCut-style .h5 or .csv file. + """ + + file = _validate_file_path(file_path=file_path, expected_suffix=[".csv"]) + _validate_dataset(ds) + to_dlc_file(ds, file.path, split_individuals=True)
+ + +
[docs]def to_sleap_analysis_file( + ds: xr.Dataset, file_path: Union[str, Path] +) -> None: + """Save the xarray dataset containing pose tracks to a SLEAP-style + .h5 analysis file. + + Parameters + ---------- + ds : xarray.Dataset + Dataset containing pose tracks, confidence scores, and metadata. + file_path : pathlib.Path or str + Path to the file to save the poses to. The file extension must be .h5. + + Notes + ----- + The output file will contain the following keys (as in SLEAP .h5 analysis + files): + "track_names", "node_names", "tracks", "track_occupancy", "point_scores", + "instance_scores", "tracking_scores", "labels_path", "edge_names", + "edge_inds", "video_path", "video_ind", "provenance" [1]_. + However, only "track_names", "node_names", "tracks", "track_occupancy" + and "point_scores" will contain data extracted from the input dataset. + "labels_path" will contain the path to the input file only if the source + file of the dataset is a SLEAP .slp file. Otherwise, it will be an empty + string. + The other attributes and data variables that are not present in the input + dataset will contain default (empty) values. + + References + ---------- + .. [1] https://sleap.ai/api/sleap.info.write_tracking_h5.html + + Examples + -------- + >>> from movement.io import save_poses, load_poses + >>> ds = load_poses.from_dlc_file("path/to/file.h5") + >>> save_poses.to_sleap_analysis_file( + ... ds, "/path/to/file_sleap.analysis.h5" + ... ) + """ + + file = _validate_file_path(file_path=file_path, expected_suffix=[".h5"]) + _validate_dataset(ds) + + ds = _remove_unoccupied_tracks(ds) + + # Target shapes: + # "track_occupancy" n_frames * n_individuals + # "tracks" n_individuals * n_space * n_keypoints * n_frames + # "track_names" n_individuals + # "point_scores" n_individuals * n_keypoints * n_frames + # "instance_scores" n_individuals * n_frames + # "tracking_scores" n_individuals * n_frames + individual_names = ds.individuals.values.tolist() + n_individuals = len(individual_names) + keypoint_names = ds.keypoints.values.tolist() + # Compute frame indices from fps, if set + if ds.fps is not None: + frame_idxs = np.rint(ds.time.values * ds.fps).astype(int).tolist() + else: + frame_idxs = ds.time.values.astype(int).tolist() + n_frames = frame_idxs[-1] - frame_idxs[0] + 1 + pos_x = ds.pose_tracks.sel(space="x").values + # Mask denoting which individuals are present in each frame + track_occupancy = (~np.all(np.isnan(pos_x), axis=2)).astype(int) + tracks = np.transpose(ds.pose_tracks.data, (1, 3, 2, 0)) + point_scores = np.transpose(ds.confidence.data, (1, 2, 0)) + instance_scores = np.full((n_individuals, n_frames), np.nan, dtype=float) + tracking_scores = np.full((n_individuals, n_frames), np.nan, dtype=float) + labels_path = ( + ds.source_file if Path(ds.source_file).suffix == ".slp" else "" + ) + data_dict = dict( + track_names=individual_names, + node_names=keypoint_names, + tracks=tracks, + track_occupancy=track_occupancy, + point_scores=point_scores, + instance_scores=instance_scores, + tracking_scores=tracking_scores, + labels_path=labels_path, + edge_names=[], + edge_inds=[], + video_path="", + video_ind=0, + provenance="{}", + ) + with h5py.File(file.path, "w") as f: + for key, val in data_dict.items(): + if isinstance(val, np.ndarray): + f.create_dataset( + key, + data=val, + compression="gzip", + compression_opts=9, + ) + else: + f.create_dataset(key, data=val) + logger.info(f"Saved PoseTracks dataset to {file.path}.")
+ + +def _remove_unoccupied_tracks(ds: xr.Dataset): + """Remove tracks that are completely unoccupied in the xarray dataset. + + Parameters + ---------- + ds : xarray.Dataset + Dataset containing pose tracks, confidence scores, and metadata. + + Returns + ------- + xarray.Dataset + The input dataset without the unoccupied tracks. + """ + + all_nan = ds.pose_tracks.isnull().all(dim=["keypoints", "space", "time"]) + return ds.where(~all_nan, drop=True) + + +def _validate_file_path( + file_path: Union[str, Path], expected_suffix: list[str] +) -> ValidFile: + """Validate the input file path by checking that the file has + write permission and expected suffix(es). If the file is not valid, + an appropriate error is raised. + + Parameters + ---------- + file_path : pathlib.Path or str + Path to the file to validate. + expected_suffix : list of str + Expected suffix(es) for the file. + + Returns + ------- + ValidFile + The validated file. + + Raises + ------ + OSError + If the file cannot be written. + ValueError + If the file does not have the expected suffix. + """ + + try: + file = ValidFile( + file_path, + expected_permission="w", + expected_suffix=expected_suffix, + ) + except (OSError, ValueError) as error: + logger.error(error) + raise error + return file + + +def _validate_dataset(ds: xr.Dataset) -> None: + """Validate the input dataset is an xarray Dataset with valid PoseTracks. + + Parameters + ---------- + ds : xarray.Dataset + Dataset to validate. + + Raises + ------ + ValueError + If `ds` is not an xarray Dataset with valid PoseTracks. + """ + + if not isinstance(ds, xr.Dataset): + raise log_error( + ValueError, f"Expected an xarray Dataset, but got {type(ds)}." + ) + ds.poses.validate() # validate the dataset
@@ -661,23 +889,15 @@

Source code for movement.io.save_poses

   
     
   
@@ -685,10 +905,24 @@ 

Source code for movement.io.save_poses

   
     
   
diff --git a/_modules/movement/io/validators.html b/_modules/movement/io/validators.html
index b4618941..f77f767e 100644
--- a/_modules/movement/io/validators.html
+++ b/_modules/movement/io/validators.html
@@ -27,6 +27,7 @@
 
 
 
+    
     
     
     
@@ -39,13 +40,14 @@
 
   
 
-    
+    
     
     
     
     
     
     
+    
     
     
   
@@ -121,7 +123,7 @@
   
   
   
-    

movement v0.0.11

+

movement v0.0.12

@@ -217,6 +219,18 @@ GitHub +
@@ -327,6 +341,18 @@ GitHub +
@@ -654,6 +680,9 @@

Source code for movement.io.validators

         etc.
     fps : float, optional
         Frames per second of the video. Defaults to None.
+    source_software : str, optional
+        Name of the software from which the pose tracks were loaded.
+        Defaults to None.
     """
 
     # Define class attributes
@@ -673,6 +702,10 @@ 

Source code for movement.io.validators

             converters.optional(float), _set_fps_to_none_if_invalid
         ),
     )
+    source_software: Optional[str] = field(
+        default=None,
+        validator=validators.optional(validators.instance_of(str)),
+    )
 
     # Add validators
     @tracks_array.validator
@@ -704,7 +737,11 @@ 

Source code for movement.io.validators

 
     @individual_names.validator
     def _validate_individual_names(self, attribute, value):
-        _validate_list_length(attribute, value, self.tracks_array.shape[1])
+        if self.source_software == "LightningPose":
+            # LightningPose only supports a single individual
+            _validate_list_length(attribute, value, 1)
+        else:
+            _validate_list_length(attribute, value, self.tracks_array.shape[1])
 
     @keypoint_names.validator
     def _validate_keypoint_names(self, attribute, value):
@@ -772,23 +809,15 @@ 

Source code for movement.io.validators

   
     
   
@@ -796,10 +825,24 @@ 

Source code for movement.io.validators

   
     
   
diff --git a/_modules/movement/logging.html b/_modules/movement/logging.html
index e506e563..c2ab7954 100644
--- a/_modules/movement/logging.html
+++ b/_modules/movement/logging.html
@@ -27,6 +27,7 @@
 
 
 
+    
     
     
     
@@ -39,13 +40,14 @@
 
   
 
-    
+    
     
     
     
     
     
     
+    
     
     
   
@@ -121,7 +123,7 @@
   
   
   
-    

movement v0.0.11

+

movement v0.0.12

@@ -217,6 +219,18 @@ GitHub +
@@ -327,6 +341,18 @@ GitHub +
@@ -523,23 +549,15 @@

Source code for movement.logging

   
     
   
@@ -547,10 +565,24 @@ 

Source code for movement.logging

   
     
   
diff --git a/_sources/api/movement.io.load_poses.from_lp_file.rst.txt b/_sources/api/movement.io.load_poses.from_lp_file.rst.txt
new file mode 100644
index 00000000..8c807f45
--- /dev/null
+++ b/_sources/api/movement.io.load_poses.from_lp_file.rst.txt
@@ -0,0 +1,6 @@
+movement.io.load\_poses.from\_lp\_file
+======================================
+
+.. currentmodule:: movement.io.load_poses
+
+.. autofunction:: from_lp_file
\ No newline at end of file
diff --git a/_sources/api/movement.io.save_poses.to_lp_file.rst.txt b/_sources/api/movement.io.save_poses.to_lp_file.rst.txt
new file mode 100644
index 00000000..7e293669
--- /dev/null
+++ b/_sources/api/movement.io.save_poses.to_lp_file.rst.txt
@@ -0,0 +1,6 @@
+movement.io.save\_poses.to\_lp\_file
+====================================
+
+.. currentmodule:: movement.io.save_poses
+
+.. autofunction:: to_lp_file
\ No newline at end of file
diff --git a/_sources/api/movement.io.save_poses.to_sleap_analysis_file.rst.txt b/_sources/api/movement.io.save_poses.to_sleap_analysis_file.rst.txt
new file mode 100644
index 00000000..197ac9af
--- /dev/null
+++ b/_sources/api/movement.io.save_poses.to_sleap_analysis_file.rst.txt
@@ -0,0 +1,6 @@
+movement.io.save\_poses.to\_sleap\_analysis\_file
+=================================================
+
+.. currentmodule:: movement.io.save_poses
+
+.. autofunction:: to_sleap_analysis_file
\ No newline at end of file
diff --git a/_sources/api/movement.io.validators.ValidPoseTracks.rst.txt b/_sources/api/movement.io.validators.ValidPoseTracks.rst.txt
index 244571fc..d02a8d8f 100644
--- a/_sources/api/movement.io.validators.ValidPoseTracks.rst.txt
+++ b/_sources/api/movement.io.validators.ValidPoseTracks.rst.txt
@@ -28,5 +28,6 @@
       ~ValidPoseTracks.individual_names
       ~ValidPoseTracks.keypoint_names
       ~ValidPoseTracks.fps
+      ~ValidPoseTracks.source_software
    
    
\ No newline at end of file
diff --git a/_sources/api_index.rst.txt b/_sources/api_index.rst.txt
index b51367eb..c191e086 100644
--- a/_sources/api_index.rst.txt
+++ b/_sources/api_index.rst.txt
@@ -13,6 +13,7 @@ Input/Output
     from_sleap_file
     from_dlc_file
     from_dlc_df
+    from_lp_file
 
 .. currentmodule:: movement.io.save_poses
 .. autosummary::
@@ -20,6 +21,8 @@ Input/Output
 
     to_dlc_file
     to_dlc_df
+    to_sleap_analysis_file
+    to_lp_file
 
 .. currentmodule:: movement.io.validators
 .. autosummary::
diff --git a/_sources/community/roadmap.md.txt b/_sources/community/roadmap.md.txt
index e5e5629b..799f4c95 100644
--- a/_sources/community/roadmap.md.txt
+++ b/_sources/community/roadmap.md.txt
@@ -19,7 +19,7 @@ The following features are being considered for the first stable version `v1.0`.
 ## Short-term milestone - `v0.1`
 We plan to release version `v0.1` of movement in early 2024, providing a minimal set of features to demonstrate the project's potential and to gather feedback from users. At minimum, it should include the following features:
 
-- Importing pose tracks from [DeepLabCut](dlc:) and [SLEAP](sleap:) into a common `xarray.Dataset` structure. This has been largely accomplished, but some remaining work is required to handle special cases.
+- Importing pose tracks from [DeepLabCut](dlc:), [SLEAP](sleap:) and [LightningPose](lp:) into a common `xarray.Dataset` structure. This has been already accomplished.
 - Visualisation of pose tracks using [napari](napari:). We aim to represent pose tracks via the [napari tracks layer](napari:howtos/layers/tracks) and overlay them on a video frame. This should be accompanied by a minimal GUI widget to allow selection of a subset of the tracks to plot. This line of work is still in a pilot phase. We may decide to use a different visualisation framework if we encounter roadblocks.
 - At least one function for cleaning the pose tracks. Once the first one is in place, it can serve as a template for others.
 - Computing velocity and acceleration from pose tracks. Again, this should serve as a template for other kinematic variables.
diff --git a/_sources/examples/load_and_explore_poses.rst.txt b/_sources/examples/load_and_explore_poses.rst.txt
index fb605a3e..f6f8292b 100644
--- a/_sources/examples/load_and_explore_poses.rst.txt
+++ b/_sources/examples/load_and_explore_poses.rst.txt
@@ -148,7 +148,7 @@ Load the dataset
 .. GENERATED FROM PYTHON SOURCE LINES 40-43
 
 The loaded dataset contains two data variables:
-``pose_tracks`` and ``confidence```
+``pose_tracks`` and ``confidence``.
 To get the pose tracks:
 
 .. GENERATED FROM PYTHON SOURCE LINES 43-45
@@ -224,7 +224,7 @@ using ``xarray``'s built-in plotting methods:
  .. code-block:: none
 
 
-    
+    
 
 
 
@@ -255,7 +255,7 @@ for all individuals:
  .. code-block:: none
 
 
-    
+    
 
 
 
@@ -299,14 +299,14 @@ For example, we can use ``matplotlib`` to plot trajectories
  .. code-block:: none
 
 
-    
+    
 
 
 
 
 .. rst-class:: sphx-glr-timing
 
-   **Total running time of the script:** (0 minutes 0.720 seconds)
+   **Total running time of the script:** (0 minutes 0.741 seconds)
 
 
 .. _sphx_glr_download_examples_load_and_explore_poses.py:
diff --git a/_sources/examples/sg_execution_times.rst.txt b/_sources/examples/sg_execution_times.rst.txt
index 0dedf237..1fa84721 100644
--- a/_sources/examples/sg_execution_times.rst.txt
+++ b/_sources/examples/sg_execution_times.rst.txt
@@ -6,7 +6,7 @@
 
 Computation times
 =================
-**00:00.720** total execution time for 1 file **from examples**:
+**00:00.741** total execution time for 1 file **from examples**:
 
 .. container::
 
@@ -33,5 +33,5 @@ Computation times
      - Time
      - Mem (MB)
    * - :ref:`sphx_glr_examples_load_and_explore_poses.py` (``load_and_explore_poses.py``)
-     - 00:00.720
+     - 00:00.741
      - 0.0
diff --git a/_sources/getting_started.md.txt b/_sources/getting_started.md.txt
index d3513543..bf7b7a26 100644
--- a/_sources/getting_started.md.txt
+++ b/_sources/getting_started.md.txt
@@ -61,13 +61,13 @@ First import the `movement.io.load_poses` module:
 from movement.io import load_poses
 ```
 
-Then, use the `from_dlc_file` or `from_sleap_file` functions to load the data.
+Then, depending on the source of your data, use one of the following functions:
 
 ::::{tab-set}
 
 :::{tab-item} SLEAP
 
-Load from [SLEAP analysis files](sleap:tutorials/analysis) (`.h5`):
+Load from [SLEAP analysis files](sleap:tutorials/analysis) (.h5):
 ```python
 ds = load_poses.from_sleap_file("/path/to/file.analysis.h5", fps=30)
 ```
@@ -75,12 +75,12 @@ ds = load_poses.from_sleap_file("/path/to/file.analysis.h5", fps=30)
 
 :::{tab-item} DeepLabCut
 
-Load pose estimation outputs from `.h5` files:
+Load pose estimation outputs from .h5 files:
 ```python
 ds = load_poses.from_dlc_file("/path/to/file.h5", fps=30)
 ```
 
-You may also load `.csv` files (assuming they are formatted as DeepLabCut expects them):
+You may also load .csv files (assuming they are formatted as DeepLabCut expects them):
 ```python
 ds = load_poses.from_dlc_file("/path/to/file.csv", fps=30)
 ```
@@ -95,6 +95,14 @@ ds = load_poses.from_dlc_df(df, fps=30)
 ```
 :::
 
+:::{tab-item} LightningPose
+
+Load from LightningPose (LP) files (.csv):
+```python
+ds = load_poses.from_lp_file("/path/to/file.analysis.csv", fps=30)
+```
+:::
+
 ::::
 
 You can also try movement out on some sample data included in the package.
@@ -144,6 +152,8 @@ representation of the dataset by simply typing its name - e.g. `ds` - in a cell.
 
 ### Dataset structure
 
+![](_static/dataset_structure.png)
+
 The movement `xarray.Dataset` has the following dimensions:
 - `time`: the number of frames in the video
 - `individuals`: the number of individuals in the video
@@ -206,19 +216,67 @@ to visualise the data. Check out the [Load and explore pose tracks](./examples/l
 example for inspiration.
 
 ## Saving data
-You can save movement datasets to disk in a variety of formats.
-Currently, only saving to DeepLabCut-style files is supported.
+You can save movement datasets to disk in a variety of formats, including
+DeepLabCut-style files (.h5 or .csv) and [SLEAP-style analysis files](sleap:tutorials/analysis) (.h5).
+
+First import the `movement.io.save_poses` module:
 
 ```python
 from movement.io import save_poses
+```
 
-save_poses.to_dlc_file(ds, "/path/to/file.h5")  # preferred
+Then, depending on the desired format, use one of the following functions:
+
+:::::{tab-set}
+
+::::{tab-item} SLEAP
+
+Save to SLEAP-style analysis files (.h5):
+```python
+save_poses.to_sleap_analysis_file(ds, "/path/to/file.h5")
+```
+
+:::{note}
+When saving to SLEAP-style files, only `track_names`, `node_names`, `tracks`, `track_occupancy`,
+and `point_scores` are saved. `labels_path` will only be saved if the source
+file of the dataset is a SLEAP .slp file. Otherwise, it will be an empty string.
+Other attributes and data variables
+(i.e., `instance_scores`, `tracking_scores`, `edge_names`, `edge_inds`, `video_path`,
+`video_ind`, and `provenance`) are not currently supported. To learn more about what
+each attribute and data variable represents, see the
+[SLEAP documentation](sleap:api/sleap.info.write_tracking_h5.html#module-sleap.info.write_tracking_h5).
+:::
+::::
+
+::::{tab-item} DeepLabCut
+
+Save to DeepLabCut-style files (.h5 or .csv):
+```python
+save_poses.to_dlc_file(ds, "/path/to/file.h5")  # preferred format
 save_poses.to_dlc_file(ds, "/path/to/file.csv")
 ```
 
-Instead of saving to file directly, you can also convert the dataset to a
-DeepLabCut-style `pandas.DataFrame` first:
+Alternatively, you can first convert the dataset to a
+DeepLabCut-style `pandas.DataFrame` using the `to_dlc_df` function:
 ```python
 df = save_poses.to_dlc_df(ds)
 ```
 and then save it to file using any `pandas` method, e.g. `to_hdf` or `to_csv`.
+::::
+
+::::{tab-item} LightningPose
+
+Save to LightningPose (LP) files (.csv).
+```python
+save_poses.to_lp_file(ds, "/path/to/file.csv")
+```
+:::{note}
+Because LP saves pose estimation outputs in the same format as single-animal
+DeepLabCut projects, the above command is equivalent to:
+```python
+save_poses.to_dlc_file(ds, "/path/to/file.csv", split_individuals=True)
+```
+:::
+
+::::
+:::::
diff --git a/_sources/index.md.txt b/_sources/index.md.txt
index da59b6f0..95863aaa 100644
--- a/_sources/index.md.txt
+++ b/_sources/index.md.txt
@@ -1,7 +1,7 @@
 (target-movement)=
 # movement
 
-Python tools for analysing body movements across space and time, to aid the study of animal behaviour in neuroscience.
+A Python toolbox for analysing body movements across space and time, to aid the study of animal behaviour in neuroscience.
 
 ::::{grid} 1 2 2 3
 :gutter: 3
@@ -28,6 +28,8 @@ Get in touch and contribute.
 :::
 ::::
 
+![](_static/movement_overview.png)
+
 ## Overview
 
 Pose estimation tools, such as [DeepLabCut](dlc:) and [SLEAP](sleap:) are now commonplace when processing video data of animal behaviour. There is not yet a standardised, easy-to-use way to process the *pose tracks* produced from these software packages.
diff --git a/_sources/sg_execution_times.rst.txt b/_sources/sg_execution_times.rst.txt
index 5ef4ce2c..f8c672db 100644
--- a/_sources/sg_execution_times.rst.txt
+++ b/_sources/sg_execution_times.rst.txt
@@ -6,7 +6,7 @@
 
 Computation times
 =================
-**00:00.720** total execution time for 1 file **from all galleries**:
+**00:00.741** total execution time for 1 file **from all galleries**:
 
 .. container::
 
@@ -33,5 +33,5 @@ Computation times
      - Time
      - Mem (MB)
    * - :ref:`sphx_glr_examples_load_and_explore_poses.py` (``../../examples/load_and_explore_poses.py``)
-     - 00:00.720
+     - 00:00.741
      - 0.0
diff --git a/_sources/snippets/get-in-touch.md.txt b/_sources/snippets/get-in-touch.md.txt
index ab5f95c3..6e10dc3e 100644
--- a/_sources/snippets/get-in-touch.md.txt
+++ b/_sources/snippets/get-in-touch.md.txt
@@ -1,3 +1,3 @@
 :::{admonition} Get in touch
-You are welcome to chat with the team on [Zulip](movement-zulip:). You may also [open an issue](movement-github:issues) to report a bug or request a new feature.
+You are welcome to chat with the team on [Zulip](movement-zulip:). You can also [open an issue](movement-github:issues) to report a bug or request a new feature.
 :::
diff --git a/_sources/snippets/status-warning.md.txt b/_sources/snippets/status-warning.md.txt
index 64ba8431..a9ccbbb7 100644
--- a/_sources/snippets/status-warning.md.txt
+++ b/_sources/snippets/status-warning.md.txt
@@ -1,6 +1,4 @@
 :::{admonition} Status
 :class: warning
-- 🏗️ The package is currently in early development. Stay tuned ⌛
-- It is not sufficiently tested to be used for scientific analysis.
-- The interface is subject to changes.
+The package is currently in early development and the interface is subject to change. Feel free to play around and provide feedback.
 :::
diff --git a/_static/css/custom.css b/_static/css/custom.css
new file mode 100644
index 00000000..40e09e63
--- /dev/null
+++ b/_static/css/custom.css
@@ -0,0 +1,32 @@
+html[data-theme=dark] {
+    --pst-color-primary: #04B46D;
+    --pst-color-link: var(--pst-color-primary);
+  }
+
+html[data-theme=light] {
+  --pst-color-primary: #03A062;
+  --pst-color-link: var(--pst-color-primary);
+}
+
+body .bd-article-container {
+max-width: 100em !important;
+}
+
+.col {
+flex: 0 0 50%;
+max-width: 50%;
+}
+
+.img-sponsor {
+height: 50px;
+padding-top: 5px;
+padding-right: 5px;
+padding-bottom: 5px;
+padding-left: 5px;
+}
+
+.things-in-a-row {
+display: flex;
+flex-wrap: wrap;
+justify-content: space-between;
+}
diff --git a/_static/dark-logo-gatsby.png b/_static/dark-logo-gatsby.png
new file mode 100644
index 00000000..97cb5036
Binary files /dev/null and b/_static/dark-logo-gatsby.png differ
diff --git a/_static/dark-logo-niu.png b/_static/dark-logo-niu.png
new file mode 100644
index 00000000..324b1bca
Binary files /dev/null and b/_static/dark-logo-niu.png differ
diff --git a/_static/dark-logo-swc.png b/_static/dark-logo-swc.png
new file mode 100644
index 00000000..845c93cd
Binary files /dev/null and b/_static/dark-logo-swc.png differ
diff --git a/_static/dark-logo-ucl.png b/_static/dark-logo-ucl.png
new file mode 100644
index 00000000..2f9b77c2
Binary files /dev/null and b/_static/dark-logo-ucl.png differ
diff --git a/_static/dark-wellcome-logo.png b/_static/dark-wellcome-logo.png
new file mode 100644
index 00000000..9af15310
Binary files /dev/null and b/_static/dark-wellcome-logo.png differ
diff --git a/_static/dataset_structure.png b/_static/dataset_structure.png
new file mode 100644
index 00000000..36bc595d
Binary files /dev/null and b/_static/dataset_structure.png differ
diff --git a/_static/documentation_options.js b/_static/documentation_options.js
index f69e53b4..6270b2c8 100644
--- a/_static/documentation_options.js
+++ b/_static/documentation_options.js
@@ -1,6 +1,6 @@
 var DOCUMENTATION_OPTIONS = {
     URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
-    VERSION: '0.0.11',
+    VERSION: '0.0.12',
     LANGUAGE: 'en',
     COLLAPSE_INDEX: false,
     BUILDER: 'html',
diff --git a/_static/light-logo-gatsby.png b/_static/light-logo-gatsby.png
new file mode 100644
index 00000000..d191f1aa
Binary files /dev/null and b/_static/light-logo-gatsby.png differ
diff --git a/_static/light-logo-niu.png b/_static/light-logo-niu.png
new file mode 100644
index 00000000..efba9404
Binary files /dev/null and b/_static/light-logo-niu.png differ
diff --git a/_static/light-logo-swc.png b/_static/light-logo-swc.png
new file mode 100644
index 00000000..98f29491
Binary files /dev/null and b/_static/light-logo-swc.png differ
diff --git a/_static/light-logo-ucl.png b/_static/light-logo-ucl.png
new file mode 100644
index 00000000..9222f876
Binary files /dev/null and b/_static/light-logo-ucl.png differ
diff --git a/_static/light-wellcome-logo.png b/_static/light-wellcome-logo.png
new file mode 100644
index 00000000..762cb392
Binary files /dev/null and b/_static/light-wellcome-logo.png differ
diff --git a/_static/movement_overview.png b/_static/movement_overview.png
new file mode 100644
index 00000000..8af12daa
Binary files /dev/null and b/_static/movement_overview.png differ
diff --git a/api/movement.datasets.fetch_pose_data_path.html b/api/movement.datasets.fetch_pose_data_path.html
index 2330741c..2eaa907b 100644
--- a/api/movement.datasets.fetch_pose_data_path.html
+++ b/api/movement.datasets.fetch_pose_data_path.html
@@ -28,6 +28,7 @@
 
 
 
+    
     
     
     
@@ -40,13 +41,14 @@
 
   
 
-    
+    
     
     
     
     
     
     
+    
     
     
     
@@ -124,7 +126,7 @@
   
   
   
-    

movement v0.0.11

+

movement v0.0.12

@@ -220,6 +222,18 @@ GitHub +
@@ -334,6 +348,18 @@ GitHub +
@@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -551,10 +572,24 @@

    movement.datasets.fetch_pose_data_path - +

    diff --git a/api/movement.datasets.list_pose_data.html b/api/movement.datasets.list_pose_data.html index 12718a84..300b7313 100644 --- a/api/movement.datasets.list_pose_data.html +++ b/api/movement.datasets.list_pose_data.html @@ -28,6 +28,7 @@ + @@ -40,13 +41,14 @@ - + + @@ -124,7 +126,7 @@ -

    movement v0.0.11

    +

    movement v0.0.12

    @@ -220,6 +222,18 @@ GitHub + @@ -334,6 +348,18 @@ GitHub + @@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -334,6 +348,18 @@ GitHub + @@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -334,6 +348,18 @@ GitHub + @@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -334,6 +348,18 @@ GitHub + @@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -334,6 +348,18 @@ GitHub + @@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -334,6 +348,18 @@ GitHub + @@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -334,6 +348,18 @@ GitHub + @@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -334,6 +348,18 @@ GitHub + @@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -619,23 +664,15 @@

    movement.io.validators.ValidPoseTracks - - - @@ -643,10 +680,24 @@

    movement.io.validators.ValidPoseTracks - + diff --git a/api/movement.io.validators.ValidPosesCSV.html b/api/movement.io.validators.ValidPosesCSV.html index 4387ae77..a38936df 100644 --- a/api/movement.io.validators.ValidPosesCSV.html +++ b/api/movement.io.validators.ValidPosesCSV.html @@ -28,6 +28,7 @@ + @@ -40,13 +41,14 @@ - + + @@ -124,7 +126,7 @@ -

    movement v0.0.11

    +

    movement v0.0.12

    @@ -220,6 +222,18 @@ GitHub + @@ -334,6 +348,18 @@ GitHub + @@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -334,6 +348,18 @@ GitHub + @@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -334,6 +348,18 @@ GitHub + @@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -333,6 +347,18 @@ GitHub + @@ -348,10 +374,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file
  • @@ -334,6 +348,18 @@ GitHub + @@ -349,10 +375,13 @@
  • movement.io.load_poses.from_sleap_file
  • movement.io.load_poses.from_dlc_file
  • movement.io.load_poses.from_dlc_df
  • +
  • movement.io.load_poses.from_lp_file