audio_synch_tool package¶
Submodules¶
audio_synch_tool.mvn module¶
This module contains functionality concerning the adaption of the XSENS MVN-XML format into our Python setup.
- The official explanation can be found in section 14.4 of this document::
- https://usermanual.wiki/Document/MVNUserManual.1147412416.pdf
A copy is stored in this repository.
The following section introduces more informally the contents of the imported MVN file and the way they can be accessed from Python:
# load mvn schema https://www.xsens.com/mvn/mvnx/schema.xsd
mvn_path = "XXX"
mmvn = Mvn(mvn_path, validate=True)
# These elements contain some small metadata:
mmvn.mvn.attrib
mmvn.mvn.comment.attrib
mmvn.mvn.securityCode.attrib["code"]
mmvn.mvn.subject.attrib
# subject.segments contain 3D pos_b labels:
for ch in mmvn.mvn.subject.segments.iterchildren():
ch.attrib, [p.attrib for p in ch.points.iterchildren()]
# Segments can look as follows: ``['Pelvis', 'L5', 'L3', 'T12', 'T8', 'Neck',
'Head', 'RightShoulder', 'RightUpperArm', 'RightForeArm', 'RightHand',
'LeftShoulder', 'LeftUpperArm', 'LeftForeArm', 'LeftHand', 'RightUpperLeg',
'RightLowerLeg', 'RightFoot', 'RightToe', 'LeftUpperLeg', 'LeftLowerLeg',
'LeftFoot', 'LeftToe']``
# sensors is basically a list of names
for s in mmvn.mvn.subject.sensors.iterchildren():
s.attrib
# Joints is a list that connects segment points:
for j in mmvn.mvn.subject.joints.iterchildren():
j.attrib["label"], j.getchildren()
# miscellaneous:
for j in mmvn.mvn.subject.ergonomicJointAngles.iterchildren():
j.attrib, j.getchildren()
for f in mmvn.mvn.subject.footContactDefinition.iterchildren():
f.attrib, f.getchildren()
# The bulk of the data is in the frames.
print("frames_metadata:", mmvn.frames_metadata)
print("first_frame_type:", mmvn.config_frames[0]["type"])
print("normal_frames_type:", mmvn.normal_frames[0]["type"])
print("num_normal_frames:", len(mmvn.normal_frames))
# Metadata looks like this:
{'segmentCount': '23', 'sensorCount': '17', 'jointCount': '22'}
# config frames have the following fields:
['orientation', 'position', 'time', 'tc', 'ms', 'type']
# normal frames have the following fields:
['orientation', 'position', 'velocity', 'acceleration',
'angularVelocity', 'angularAcceleration', 'footContacts',
'sensorFreeAcceleration', 'sensorMagneticField', 'sensorOrientation',
'jointAngle', 'jointAngleXZY', 'jointAngleErgo', 'centerOfMass', 'time',
'index', 'tc', 'ms', 'type']
The following fields contain metadata about the frame:
time: | ms since start (integer). It is close to
int(1000.0 * index / samplerate) , being equal most of the times and
at most 1 milisecond away. It is neither truncated nor rounded, maybe it
is given by the hardware. |
---|---|
index: | starts with 0, +1 each normal frame |
tc: | string like ‘02:23:28:164’ |
ms: | unix timestamp like 1515983008686 (used to compute time) |
type: | one of “identity”, “tpose”, “tpose-isb”, “normal” |
# The following fields are float vectors of the following dimensionality:
orientation: | segmentCount*4 = 92 Quaternion vector |
---|---|
position, velocity, acceleration, angularVelocity, angularAcceleration: | |
segmentCount*3 = 69 3D vectors in (x,y,z) format |
|
footContacts: | 4 4D boolean vector |
sensorFreeAcceleration, sensorMagneticField: | |
sensorCount*3 = 51 |
|
sensorOrientation: | |
sensorCount*4 = 68 |
|
jointAngle, jointAngleXZY: | |
jointCount*3 = 66 |
|
jointAngleErgo: | 12 |
centerOfMass: | 3 |
The units are SI for position, velocity and acceleration. Angular magnitudes
are in radians except the jointAngle...
ones that are in degrees. All 3D
vectors are in (x,y,z)
format, but the jointAngle...
ones differ in
the Euler-rotation order by which they are computed (ZXY, standard or XZY,
for shoulders usually).
-
class
audio_synch_tool.mvn.
Mvn
(mvn_path, validate=False)[source]¶ Bases:
object
This class imports and adapts an XML file (expected to be in MVN format) to a Python-friendly representation. See this module’s docstring for usage examples and more information.
-
MVNX_SCHEMA_PATH
= '/home/docs/checkouts/readthedocs.org/user_builds/audio-synch-tool/checkouts/latest/audio_synch_tool/data/mvn_schema_adapted.xsd'¶
-
export
(filepath, pretty_print=True, extra_comment='')[source]¶ Saves the current
mvn
attribute to the given file path as XML and adds theself.mvn.attrib["pythonComment"]
attribute with a timestamp.
-
static
extract_frames
(mvn)[source]¶ The bulk of the MVN file is the
mvn->subject->frames
section. This function parses it and returns its information in a python-friendly format.Parameters: mvn – An XML tree, expected to be in MVN format Returns: a tuple (frames_metadata, config_frames, normal_frames)
where the metadata is a dict in the form{'segmentCount': '23', 'sensorCount': '17', 'jointCount': '22'}
, the config frames are the first 3 frame entries (expected to contain special config info) and the normal_frames are all frames starting from the 4th. Both frame outputs are relational collections of dictionaries that can be formatted into tabular form.
-
static
extract_normalframe_magnitudes
(normal_frames)[source]¶ Returns: A list of the magnitude names in each of the self.normal_frames
-
extract_normalframe_sequences
(frames_metadata, normal_frames)[source]¶ Returns: a dict with np arrays of shape (num_normalframes, num_channels)
where the number of channels is e.g. 1 for scalar magnitudes, 3 for 3D vectors (in xyz format)…
-
extract_segments
()[source]¶ Returns: A list of the segment names in self.mvn.subject.segments
, ordered by id (starting at 1 and incrementing +1).
-
get_audio_synch
()[source]¶ Returns: a list with the audio_sample
attributes for the normal frames, or None if there is at least 1 normal frame without theaudio_sample
attribute. Note that this function assumes that the entries are integers in the form ‘123’, so they are retrieved int(x). If that is not the case, they may be truncated or even throw an exception.
-
set_audio_synch
(stretch, shift)[source]¶ Given the list of normal frames in this Mvn, each one with an “index” field, this function adds an
audio_sample
attribute to each frame, whereaudio_sample = round(index * stretch + shift)
. Seeutils.convert_anchors
for converting anchor points into stretch and shift.
-
audio_synch_tool.plotters module¶
audio_synch_tool.utils module¶
-
class
audio_synch_tool.utils.
DownsamplableFunction
(y_arr, max_datapoints, x_arr=None)[source]¶ Bases:
object
Encapsulates the downsampling functionality to prevent side effects, and reduce code verbosity in plotter.
-
class
audio_synch_tool.utils.
IdentityFormatter
[source]¶ Bases:
object
This functor can be passed to
plt.FuncFormatter
to generate custom tick labels. It fulfills the interface (val, pos)->str.Specifically, for a given
val
returnsstr(val)
. In most cases this is the default matplotlib behaviour, but using this formatter forces it to behave ALWAYS like this and avoid some other smart conversions like scientific notation for big numbers.
-
class
audio_synch_tool.utils.
ProportionalFormatter
(ratio, num_decimals=3)[source]¶ Bases:
object
This functor can be passed to
plt.FuncFormatter
to generate custom tick labels. It fulfills the interface (val, pos)->str.Specifically, converts
val
number representing a sample into a string in the formval [val2]
whereval2 = val * ratio
. This can be useful e.g. to show the original values if the signal was resampled.
-
class
audio_synch_tool.utils.
SampleToTimestampFormatter
(samplerate, num_decimals=3, show_idx=True)[source]¶ Bases:
object
This functor can be passed to
plt.FuncFormatter
to generate custom tick labels. It fulfills the interface (val, pos)->str.Specifically, converts
val
number representing a sample into a string showing the corresponding elapsed time since sample 0, asuming the given samplerate. Usage example:ax.xaxis.set_major_formatter(plt.FuncFormatter( SampleToTimestampFormatter(sr)))
Bases:
object
If multiple axes share the x-limits, calling the functor from one of them triggers a call for every one of them.
-
class
audio_synch_tool.utils.
SynchedMvnFormatter
(mvn, num_decimals=3)[source]¶ Bases:
object
This functor can be passed to
plt.FuncFormatter
to generate custom tick labels. It fulfills the interface (val, pos)->str.Specifically, it looks in the MVN file for the frame index with the given
val
and, if found, returns the stringval [frame_idx]
(otherwise just val). For that, it expects that the frame has defined theaudio_sample
attribute.
-
class
audio_synch_tool.utils.
Timedelta
(sample_nr, samplerate)[source]¶ Bases:
object
-
days
¶
-
hours
¶
-
microsecs
¶
-
mins
¶
-
sample_nr
¶
-
samplerate
¶
-
secs
¶
-
total_seconds
¶
-
-
class
audio_synch_tool.utils.
XlimCallbackFunctor
(axis, lines, arrays, shared_axes, verbose=False)[source]¶ Bases:
object
Encapsulates the downsampling callback functionality to prevent side effects. Instances of this functor can be passed to an axis like this:
``ax.callbacks.connect('xlim_changed', DownsamplingCallbackFunctor(ax, [line1..], [arr1...]))``
-
audio_synch_tool.utils.
convert_anchors
(ori1, dest1, ori2, dest2)[source]¶ Given a signal that we want to shift and stretch on the x axis, this affine operation can be defined by picking 2 points of the signal (ori1 and ori2, called here “anchors”), and mapping them to other 2 points (dest1 and dest2). For the given anchors, this function returns the corresponding stretching ratio and shifting amount (after stretching) needed to match the given anchors. This is given by solving the formula:
``[dest1, dest2] = shift + stretch * [ori1, ori2]``
Parameters: ori1 (number) – any real-valued number. Same for ori2, dest1, dest2. Returns: a tuple (stretch, shift) with 2 real-valued numbers.
-
audio_synch_tool.utils.
make_timestamp
(timezone='Europe/Berlin')[source]¶ Output example: day, month, year, hour, min, sec, milisecs: 10_Feb_2018_20:10:16.151
-
audio_synch_tool.utils.
resolve_path
(*path_elements)[source]¶ A convenience path wrapper to find elements in this package. Retrieves the absolute path, given the OS-agnostic path relative to the package root path (by bysically joining the path elements via
os.path.join
). E.g., the following call retrieves the absolute path for<PACKAGE_ROOT>/a/b/test.txt
:resolve_path("a", "b", "test.txt")
Params strings path_elements: From left to right, the path nodes, the last one being the filename. Return type: str