Skip to content

Commit

Permalink
Removed deprecated functions in ktk.kinematics
Browse files Browse the repository at this point in the history
  • Loading branch information
felixchenier committed Mar 6, 2024
1 parent fe2d4c9 commit a22b832
Show file tree
Hide file tree
Showing 3 changed files with 2 additions and 230 deletions.
157 changes: 1 addition & 156 deletions kineticstoolkit/kinematics.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@


import kineticstoolkit.geometry as geometry
from kineticstoolkit import TimeSeries, read_c3d, write_c3d
from kineticstoolkit.decorators import deprecated
from kineticstoolkit import TimeSeries
from kineticstoolkit.typing_ import check_param

import numpy as np
import warnings
import struct # To unpack data from N3D files


def __dir__():
Expand Down Expand Up @@ -338,156 +336,3 @@ def write_trc_file(markers: TimeSeries, /, filename: str) -> None:
+ "\t{:.5f}".format(markers.data[key][i_frame, 2])
)
fid.write("\n")


# %% Deprecated
@deprecated(
since="0.9",
until="2024",
details=(
"Please use the ktk.read_c3d() function that is more powerful "
"since it can also read analog data."
),
)
def read_c3d_file(filename: str) -> TimeSeries:
"""
Read markers from a C3D file.
The markers positions are returned in a TimeSeries where each marker
corresponds to a data key. Each marker position is expressed in this form:
array([[x0, y0, z0, 1.], [x1, y1, z1, 1.], [x2, y2, z2, 1.], ...])
Parameters
----------
filename
Path of the C3D file
Notes
-----
- This function relies on `ezc3d`, which is available on
conda-forge and on git-hub. Please install ezc3d before using
read_c3d_file. https://github.com/pyomeca/ezc3d
- The point unit must be either mm or m. In both cases, the final unit
returned in the output TimeSeries is m.
- As for any instrument, please check that your data loads correctly on
your first use (e.g., sampling frequency, position unit). It is
possible that read_c3d_file misses some corner cases.
"""
return read_c3d(filename)["Points"]


@deprecated(
since="0.9",
until="2024",
details=(
"Please use the ktk.write_c3d() function that is more powerful "
"since it can also write analog data."
),
)
def write_c3d_file(filename: str, markers: TimeSeries) -> None:
"""
Write a markers TimeSeries to a C3D file.
Parameters
----------
filename
Path of the C3D file
markers
Markers trajectories, following the same form as the TimeSeries
read by read_c3d_file.
Notes
-----
This function relies on `ezc3d`. Please install ezc3d before using
write_c3d_file. https://github.com/pyomeca/ezc3d
"""
write_c3d(filename, markers)


@deprecated(
since="0.9",
until="2024",
details=("This function has been moved to the n3d extension."),
)
def read_n3d_file(filename: str, labels: list[str] = []) -> TimeSeries:
"""
Read markers from an NDI N3D file.
The markers positions are returned in a TimeSeries where each marker
corresponds to a data key. Each marker position is expressed in this form:
array([[x0, y0, z0, 1.], [x1, y1, z1, 1.], [x2, y2, z2, 1.], ...])
Parameters
----------
filename : str
Path of the N3D file.
labels : list of str (optional)
Marker names
Returns
-------
TimeSeries
"""
with open(filename, "rb") as fid:
_ = fid.read(1) # 32
n_markers = struct.unpack("h", fid.read(2))[0]
n_data_per_marker = struct.unpack("h", fid.read(2))[0]
n_columns = n_markers * n_data_per_marker

n_frames = struct.unpack("i", fid.read(4))[0]

collection_frame_frequency = struct.unpack("f", fid.read(4))[0]
user_comments = struct.unpack("60s", fid.read(60))[0]
system_comments = struct.unpack("60s", fid.read(60))[0]
file_description = struct.unpack("30s", fid.read(30))[0]
cutoff_filter_frequency = struct.unpack("h", fid.read(2))[0]
time_of_collection = struct.unpack("8s", fid.read(8))[0]
_ = fid.read(2)
date_of_collection = struct.unpack("8s", fid.read(8))[0]
extended_header = struct.unpack("73s", fid.read(73))[0]

# Read the rest and put it in an array
ndi_array = np.ones((n_frames, n_columns)) * np.NaN

for i_frame in range(n_frames):
for i_column in range(n_columns):
data = struct.unpack("f", fid.read(4))[0]
if data < -1e25: # technically, it is -3.697314e+28
data = np.NaN
ndi_array[i_frame, i_column] = data

# Conversion from mm to meters
ndi_array /= 1000

# Transformation to a TimeSeries
ts = TimeSeries(
time=np.linspace(
0, n_frames / collection_frame_frequency, n_frames
)
)

for i_marker in range(n_markers):
if labels != []:
label = labels[i_marker]
else:
label = f"Marker{i_marker}"

ts.data[label] = np.block(
[
[
ndi_array[:, 3 * i_marker : 3 * i_marker + 3],
np.ones((n_frames, 1)),
]
]
)
ts = ts.add_data_info(label, "Unit", "m")

return ts
4 changes: 0 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ line-length = 79
[tool.pytest.ini_options]
filterwarnings = [
# TO REMOVE IN 2024
# kinematics
'ignore:The function read_c3d_file is deprecated since 0.9 and is scheduled to be removed in 2024:FutureWarning',
'ignore:The function read_n3d_file is deprecated since 0.9 and is scheduled to be removed in 2024:FutureWarning',

# TimeSeries
'ignore:The function get_ts_at_event is deprecated since 0.10.0 and is scheduled to be removed in 2024:FutureWarning',
'ignore:The function get_event_time is deprecated since 0.10.0 and is scheduled to be removed in 2024:FutureWarning',
Expand Down
71 changes: 1 addition & 70 deletions tests/test_kinematics.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,75 +28,6 @@

import kineticstoolkit as ktk
import numpy as np
import warnings
import os


def test_read_n3d_file_deprecated():
"""Regression test."""
markers = ktk.kinematics.read_n3d_file(
ktk.doc.download("kinematics_sample_optotrak.n3d")
)

tol = 1e-4
assert np.abs(np.sum(markers.data["Marker0"]) - 172.3365) < tol
assert np.abs(np.sum(markers.data["Marker40"]) + 45.3753) < tol
assert markers.time_info["Unit"] == "s"
assert markers.data_info["Marker40"]["Unit"] == "m"

labels = [
"Probe1",
"Probe2",
"Probe3",
"Probe4",
"Probe5",
"Probe6",
"FRArrD",
"FRArrG",
"FRav",
"ScapulaG1",
"ScapulaG2",
"ScapulaG3",
"ScapulaD1",
"ScapulaD2",
"ScapulaD3",
"Tete1",
"Tete2",
"Tete3",
"Sternum",
"BrasG1",
"BrasG2",
"BrasG3",
"EpicondyleLatG",
"AvBrasG1",
"AvBrasG2",
"AvBrasG3",
"NAG",
"GantG1",
"GantG2",
"GantG3",
"BrasD1",
"BrasD2",
"BrasD3",
"EpicondyleLatD",
"AvBrasD1",
"AvBrasD2",
"AvBrasD3",
"NAD",
"GantD1",
"GantD2",
"GantD3",
]

markers = ktk.kinematics.read_n3d_file(
ktk.doc.download("kinematics_sample_optotrak.n3d"),
labels=labels,
)

assert np.abs(np.sum(markers.data["Probe1"]) - 172.3365) < tol
assert np.abs(np.sum(markers.data["GantD3"]) + 45.3753) < tol
assert markers.time_info["Unit"] == "s"
assert markers.data_info["GantD3"]["Unit"] == "m"


def test_reconstruction():
Expand Down Expand Up @@ -134,7 +65,7 @@ def test_reconstruction():

def process_probing_acquisition(file_name, cluster, point_name):
# Load the markers
markers_probing = ktk.kinematics.read_c3d(file_name)["Points"]
markers_probing = ktk.read_c3d(file_name)["Points"]

# Find the probe tip
markers_probing.merge(
Expand Down

0 comments on commit a22b832

Please sign in to comment.