From cbd0541a54170b0771268c3a534211ae715b12cd Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Sat, 1 Jun 2024 12:19:34 +0200 Subject: [PATCH] docs, fixes and test for nixtrack data wrapper --- src/etrack/io/nixtrack_data.py | 74 +++++++++++++++++- ...2022lepto01_converted_2024.03.27_0.mp4.nix | Bin 0 -> 138304 bytes test/test_nixtrackio.py | 32 ++++++++ 3 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 test/2022lepto01_converted_2024.03.27_0.mp4.nix create mode 100644 test/test_nixtrackio.py diff --git a/src/etrack/io/nixtrack_data.py b/src/etrack/io/nixtrack_data.py index 6d0ec8d..0ef6685 100644 --- a/src/etrack/io/nixtrack_data.py +++ b/src/etrack/io/nixtrack_data.py @@ -9,7 +9,8 @@ from IPython import embed class NixtrackData(object): - + """Wrapper around a nix data file that has been written accorind to the nixtrack model (https://github.com/bendalab/nixtrack) + """ def __init__(self, filename, crop=(0, 0)) -> None: """ If the video data was cropped before tracking and the tracked positions are with respect to the cropped images, we may want to correct for this to convert the data back to absolute positions in the video frame. @@ -37,28 +38,93 @@ class NixtrackData(object): @property def filename(self): + """ + Returns the name of the file associated with the NixtrackData object. + + Returns: + str: The name of the file. + """ return self._file_name @property def bodyparts(self): + """ + Returns the bodyparts of the dataset. + + Returns: + list: A list of bodyparts. + """ return self._dataset.nodes def _correct_cropping(self, orgx, orgy): + """ + Corrects the coordinates based on the cropping values, If it cropping was done during tracking. + + Args: + orgx (int): The original x-coordinate. + orgy (int): The original y-coordinate. + + Returns: + tuple: A tuple containing the corrected x and y coordinates. + """ x = orgx + self._crop[0] y = orgy + self._crop[1] return x, y - + + @property + def fps(self): + """Property that holds frames per second of the original video. + Returns + ------- + int : the frames of second + """ + return self._dataset.fps + @property def tracks(self): - return self._dataset.tracks + """ + Returns a list of tracks from the dataset. + + Returns: + list: A list of tracks. + """ + return [t[0] for t in self._dataset.tracks] + + def track_data(self, bodypart=0, track=-1, fps=None): + """ + Retrieve tracking data for a specific body part and track. + + Parameters + ---------- + bodypart : int or str + Index or name of the body part to retrieve tracking data for. + track : int or str + Index of the track to retrieve tracking data for. + fps : float + Frames per second of the tracking data. If not provided, it will be retrieved from the dataset. + + Returns + ------- + TrackingData: An object containing the x and y positions, time, score, body part name, and frames per second. - def track(self, bodypart=0, fps=None): + Raises + ------ + ValueError: If the body part or track is not valid. + """ if isinstance(bodypart, nb.Number): bp = self.bodyparts[bodypart] elif isinstance(bodypart, (str)) and bodypart in self.bodyparts: bp = bodypart else: raise ValueError(f"Body part {bodypart} is not a tracked node!") + + if track not in self.tracks: + raise ValueError(f"Track {track} is not a valid track name!") + if not isinstance(track, (list, tuple)): + track = [track] + elif isinstance(track, int): + track = [self.tracks[track]] + if fps is None: fps = self._dataset.fps diff --git a/test/2022lepto01_converted_2024.03.27_0.mp4.nix b/test/2022lepto01_converted_2024.03.27_0.mp4.nix new file mode 100644 index 0000000000000000000000000000000000000000..378af3a06ac161a5159fe211ca70bd8e81ffe732 GIT binary patch literal 138304 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 literal 0 HcmV?d00001 diff --git a/test/test_nixtrackio.py b/test/test_nixtrackio.py new file mode 100644 index 0000000..bce61e1 --- /dev/null +++ b/test/test_nixtrackio.py @@ -0,0 +1,32 @@ +import pytest +import etrack as et + +from IPython import embed + +dataset = "test/2022lepto01_converted_2024.03.27_0.mp4.nix" + + +@pytest.fixture +def nixtrack_data(): + # Create a NixTrackData object with some test data + return et.NixtrackData(dataset) + + +def test_basics(nixtrack_data): + assert nixtrack_data.filename == dataset + assert len(nixtrack_data.bodyparts) == 5 + assert len(nixtrack_data.tracks) == 2 + assert nixtrack_data.fps == 25 + + +def test_trackingdata(nixtrack_data): + with pytest.raises(ValueError): + nixtrack_data.track_data(bodypart="test") + nixtrack_data.track_data(track="fish") + + assert nixtrack_data.track_data("center") is not None + assert nixtrack_data.track_data("center", "none") is not None + + +if __name__ == "__main__": + pytest.main() \ No newline at end of file