pybemobil.preproc.process_rigid_body#
- pybemobil.preproc.process_rigid_body(raw, rb_names=None, lowpass_orient=6.0, lowpass_pos=6.0, lowpass_deriv=18.0, compute_velocity=True, compute_acceleration=True, sfreq_target=None, unwrap=True, angle_unit='rad')[source]#
Process rigid body motion capture streams.
For each rigid body found in raw:
Convert quaternions to Euler angles (ZYX convention = yaw-pitch-roll) if quaternion channels are present. The source quaternion channels are dropped and replaced by Euler angle channels.
Unwrap the Euler angles (see unwrap). Samples where the rigid body was not tracked are bridged by linear interpolation first: samples where all of its channels are exactly 0 (how
XDFLoaderfills dropouts), quaternions with a norm of ~0, and spans annotatedBAD_<rb>_missing. Such spans are annotatedBAD_<rb>_missingin the output, so they can be rejected later; without bridging, filtering and differentiation would turn them into huge spurious velocities.Optionally resample all channels to sfreq_target.
Optionally low-pass filter the orientation (and position) signals.
Compute the first derivative (velocity) via finite differences, with an optional low-pass filter applied after differentiation.
Compute the second derivative (acceleration) in the same way.
Derivative channels are appended to the returned raw object with the naming scheme
<rb>_<type>_vel_<axis>and<rb>_<type>_acc_<axis>, where type iseulorposso that orientation and position derivatives always have distinct names (e.g.head_eul_vel_x,head_pos_vel_x).- Parameters:
- raw
mne.io.BaseRaw Source recording. Motion channels should be of type
"misc"(which is the default when XDFLoader imports non-EEG streams).- rb_names
listofstr|None Rigid body identifiers to process. If
None, all identifiers found byfind_rigid_bodies()are processed.- lowpass_orient
float|None Low-pass cutoff (Hz) applied to orientation channels. Default
6, BeMoBIL’slowpass_motion.Noneskips this filter.- lowpass_pos
float|None Low-pass cutoff (Hz) applied to position channels. Default
6(lowpass_motion).Noneskips.- lowpass_deriv
float|None Low-pass cutoff (Hz) applied to velocity and acceleration channels after differentiation. Default
18, BeMoBIL’slowpass_motion_after_derivative.Noneskips.- compute_velocitybool
Whether to compute and append velocity channels.
- compute_accelerationbool
Whether to compute and append acceleration channels. Works with
compute_velocity=Falsetoo: the velocity is then computed internally but not appended.- sfreq_target
float|None If not
None, resample the recording to this rate after the quaternion conversion and before filtering and differentiation. Useful to match the EEG sample rate.- unwrapbool
If
True(default), unwrap the Euler angles over time (numpy.unwrap()), as in BeMoBIL. Angles wrap at ±π, so a continuous rotation otherwise produces jumps of 2π that dominate the filtered signal and its derivatives. The returned orientation channels are then continuous and may exceed ±π (±180°).- angle_unit
"rad"|"deg" Unit of Euler input channels (
<rb>_eul_*), used to unwrap them with the right period (2π or 360°). Default"rad". A warning is logged when"rad"is given but the angles exceed ±2π, which usually means degrees. Euler angles computed from quaternions are always in radians.
- raw
- Returns:
- raw_out
mne.io.Raw Copy of raw with quaternion channels replaced by Euler channels and velocity / acceleration channels appended.
- rb_info
dict Per-rigid-body processing summary:
{rb_name: {"mode": "quat->euler"|"euler", "channels": list[str], "n_missing": int}}wheren_missingis the number of bridged samples (at the input sampling rate).
- raw_out