Data representation conventions#
torch_ecg standardizes a small set of representations for signals, waveform annotations, intervals and labels. These conventions allow readers, datasets, augmenters and models to interoperate; this page documents them.
Signals: lead-first by default#
A multi-lead signal is a numpy array (or tensor) of shape
(n_leads, n_samples) — lead-first — matching
(channel, time) in PyTorch. The 12-lead order is fixed by
Standard12Leads:
from torch_ecg.utils.ecg_arrhythmia_knowledge import Standard12Leads
list(Standard12Leads)
# ['I', 'II', 'III', 'aVR', 'aVL', 'aVF', 'V1', ..., 'V6']
Use ensure_lead_fmt() when a source
uses the lead-last layout, and
ensure_siglen() to pad or crop to a
fixed length:
from torch_ecg.utils.utils_data import ensure_lead_fmt
sig # (12, 500), lead-first
ensure_lead_fmt(sig, 12, fmt="lead_last").shape # (500, 12)
Waveform masks#
Wave delineation (P/QRS/T boundaries) is carried as an integer mask
of shape ``(n_leads, n_samples)``, with a per-task class_map
assigning wave names to integers, e.g. {"pwave": 1, "qrs": 2}.
Two converters move between masks and explicit waveforms/intervals:
mask_to_intervals()works on a single lead (a 1-D mask) and returns half-open intervals[a, b)by default (right_inclusive=Trueswitches to[a, b]):mask = np.zeros(100, dtype=int) mask[10:20] = 1; mask[80:95] = 1; mask[50:60] = 2 mask_to_intervals(mask, vals=1) # [[10, 20], [80, 95]]
masks_to_waveforms()converts the full(n_leads, n_samples)mask into per-lead lists ofECGWaveFormdataclasses, withonset/offset/peakindices and adurationin milliseconds:wfs = masks_to_waveforms(mask_2d, class_map, fs=100, leads=["I", "II"]) wfs["I"][0].name, wfs["I"][0].onset, wfs["I"][0].duration # ('pwave', 10, 200.0)
Intervals and generalized intervals#
An Interval is a pair
[a, b]; a GeneralizedInterval
is a list of such pairs (a possibly non-contiguous span, e.g. the
union of all QRS complexes). The
utils_interval module provides the algebra
over them — intervals_union(),
generalized_intervals_union(),
intervals_intersection(),
generalized_interval_complement(),
length helpers, and cover-finding utilities — which the dataset
samplers use to extract training segments around annotated structures.
Labels#
Classification labels are multi-hot vectors over the task’s
classes list. one_hot_encode()
builds them from class indices, for both the single-label and the
multi-label case:
from torch_ecg.utils.utils_data import one_hot_encode
one_hot_encode([[1], [0, 2]], num_classes=3)
# array([[0., 1., 0.],
# [1., 0., 1.]], dtype=float32)
Models output raw logits over classes; the sigmoid outputs are
binarized at inference time (challenge-specific thresholds or the
default 0.5), rather than inside the model. This keeps the training loss and
the official evaluation metrics free of hard-coded decision rules.