Python Easy 接口
30 秒版本:
你只想“读出来就是数组” → 用 Easy 层。
把
View当成“数组 + 当前选择状态(labels/type-groups)”。需要更精细控制时,再下探到
View._chunk(CoreChunk)。
形象化:View 像一个小控制台,你先改选择器,再读取对应的两张表。
这层是给“直接用数据做分析/仿真”的用户准备的。你不需要先理解 chunk/query/recipe 的内部结构,只要记住:
sqzc3d.read(...)负责把数据读成一个ViewView保存当前选择状态(labels/type-groups),并以属性方式暴露数据与 validity需要高级能力时再下探到
View._chunk(CoreChunk)
如果你已经有 indices、或者需要更精细的 layout/view/copy 控制,请直接使用 Core API(Decoder / Chunk)。
读入:read
import sqzc3d as sq
v = sq.read("trial.c3d") # 从 C3D materialize
v = sq.read("trial.sqzc3d") # 加载 single-file bundle
v = sq.read("bundle_dir/") # 加载 directory bundle
常用参数:
start_frame,frame_count:按帧的 window 选择points,analogs:label 选择器analog_range:analog 的窗口选择(高级;与start_frame属于同一套“按帧计”的编号体系)label_norm:label 归一化模式(若归一化后变得不唯一,会直接报错)recipe:可复用的过滤 recipe(目前主要是 type-groups)
选择器语义:
None表示默认(ALL)[]表示空选择str或sequence[str]表示按 label 选择
窗口与时间轴
View.meta 会包含时间轴相关元数据(若可用):
source_first_frame,source_last_frame:源 C3D 的“绝对帧号”point_rate_hz,analog_rate_hz:采样率frame_start,frame_start_abs:本次 points 窗口的起点(相对 / 绝对)analog_frame_start,analog_frame_start_abs:本次 analog 窗口的起点(相对 / 绝对)
如果你希望 analog 与 points 严格对齐,请显式传入 analog_range=(start_frame, frame_count):
import sqzc3d as sq
v = sq.read("trial.c3d", start_frame=100, frame_count=200, analog_range=(100, 200))
print(v.meta["frame_start_abs"], v.meta["analog_frame_start_abs"])
选择状态:直接改 View 字段
View 把选择状态保存在字段里,你可以直接查看和修改:
import sqzc3d as sq
v = sq.read("trial.c3d")
# 查看
print(v.point_labels) # None 表示 ALL
print(v.analog_labels) # None 表示 ALL
# 修改选择(labels-only)
v.point_labels = ["LASI", "RASI"]
v.analog_labels = ["EMG1"]
关于顺序(非常重要):
当
view.point_labels被设置时,view.points会按point_labels的顺序 返回 points。当
view.analog_labels被设置时,view.analogs会按analog_labels的顺序 返回 channels。
获取数据:属性 + validity
view.points/view.points_validview.analogs/view.analogs_valid
pts = v.points
valid = v.points_valid
按 label 取单个 marker / channel
提供了按 label 的便捷访问(避免你手动去找 index):
ank = v.point["LANK"] # (T, 3)
ank_valid = v.point_valid["LANK"] # (T,)
emg = v.analog["EMG1"] # (N,) 或 (T, S)(取决于 analog_layout)
emg_valid = v.analog_valid["EMG1"]
Type-groups
可选。
如果 chunk 上有 type-groups,可将其作为额外的 AND-filter:
import sqzc3d as sq
v = sq.read("trial.c3d")
v.type_groups = ["MARKER"] # AND with point_labels if set
pts = v.points
缺失元数据时的行为:
type_groups_missing_meta="all"(默认):缺失 TYPE_GROUPS 元数据时视作 no-optype_groups_missing_meta="empty":缺失元数据时直接得到空集
严格模式:
type_groups_strict=True会在缺失/无效时直接抛错
Recipe
可选。
Recipe 是可复用的配置对象,可作为参数传入 read(...)(适合把“选择规则”抽出来复用)。
import sqzc3d as sq
rcp = sq.Recipe(
type_groups=("MARKER",),
type_groups_strict=False,
type_groups_missing_meta="all",
)
v = sq.read("trial.c3d", recipe=rcp)
print(v.describe())
进阶:进入 Core 层
不主推,但随时可用。
Easy 层会把高级能力保留为“可用但不默认”的形式。
View._chunk 暴露底层 core Chunk:
chunk = v._chunk
pts, valid = chunk.points(None, copy=False)