Python API¶
Only the stable inference surface and top-level classical orchestrator are documented as public API. Experiment support modules remain implementation details and may change without compatibility guarantees.
Browse the corresponding source modules on GitHub: inference core, predictors, and pipeline runner.
Inference data flow¶
src.ecg_sqi_inference.core.InputRecord
dataclass
¶
ECG signal loaded from one input file.
Attributes:
| Name | Type | Description |
|---|---|---|
record_id |
str
|
File-stem identifier used in output rows. |
signal |
ndarray
|
One- or two-dimensional ECG sample array. |
input_path |
Path
|
Source file path. |
Source code in src/ecg_sqi_inference/core.py
src.ecg_sqi_inference.core.SegmentPredictor ¶
Bases: Protocol
Interface implemented by segment-level inference models.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Stable model identifier written to outputs. |
n_leads |
int
|
Number of ECG leads required by the model. |
Source code in src/ecg_sqi_inference/core.py
predict ¶
Classify a batch of fixed-length ECG segments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
segments
|
ndarray
|
Array shaped as batch, samples, and leads. |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
One prediction row per input segment. |
src.ecg_sqi_inference.core.read_record ¶
Load one supported ECG file into a normalized record container.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
NPZ, NPY, CSV, or WFDB header file to read. |
required |
Returns:
| Type | Description |
|---|---|
InputRecord
|
Loaded record with a float32 signal. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the format or signal shape is unsupported. |
Example
record = read_record(Path("record.npy")) record.signal.ndim in {1, 2} True
Source code in src/ecg_sqi_inference/core.py
src.ecg_sqi_inference.core.iter_input_files ¶
List supported ECG inputs from a file or directory tree.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
Input file or directory to scan recursively. |
required |
Returns:
| Type | Description |
|---|---|
list[Path]
|
Supported files in deterministic path order. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If the input path does not exist. |
Example
files = iter_input_files(Path("input-records")) files == sorted(files) True
Source code in src/ecg_sqi_inference/core.py
src.ecg_sqi_inference.core.as_samples_by_lead ¶
Orient an ECG array as samples by the model's required leads.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signal
|
ndarray
|
One- or two-dimensional ECG array. |
required |
n_leads
|
int
|
Required model lead count, currently 1 or 12. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Float32 array shaped as samples by leads. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the signal cannot satisfy the requested lead count. |
Example
as_samples_by_lead(np.zeros((12, 1250)), 12).shape (1250, 12)
Source code in src/ecg_sqi_inference/core.py
src.ecg_sqi_inference.core.resample_signal ¶
Resample a samples-by-leads ECG array to the model frequency.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signal
|
ndarray
|
ECG array with time on axis zero. |
required |
fs
|
float
|
Source sampling frequency in hertz. |
required |
target_fs
|
int
|
Destination sampling frequency in hertz. |
MODEL_FS
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Resampled float32 ECG array. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the source frequency is not positive. |
Example
resample_signal(np.zeros((5000, 1)), 500).shape (1250, 1)
Source code in src/ecg_sqi_inference/core.py
src.ecg_sqi_inference.core.segment_signal ¶
Split ECG samples into complete non-overlapping model windows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signal
|
ndarray
|
Samples-by-leads ECG at |
required |
Returns:
| Type | Description |
|---|---|
tuple[ndarray, float]
|
Segment batch and discarded tail duration in seconds. |
Example
segments, dropped = segment_signal(np.zeros((1300, 1))) (segments.shape, dropped) ((1, 1250, 1), 0.4)
Source code in src/ecg_sqi_inference/core.py
src.ecg_sqi_inference.core.predict_records ¶
predict_records(*, input_path: Path, out_dir: Path, fs: float, predictor: SegmentPredictor) -> dict[str, object]
Run one predictor over every supported input and write CSV/JSON outputs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_path
|
Path
|
ECG file or directory tree to process. |
required |
out_dir
|
Path
|
Directory receiving per-record and combined outputs. |
required |
fs
|
float
|
Sampling frequency shared by the input records. |
required |
predictor
|
SegmentPredictor
|
Segment classifier with a name and required lead count. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, object]
|
Run summary when every discovered record succeeds. |
Raises:
| Type | Description |
|---|---|
SystemExit
|
If one or more records fail; outputs and a failure summary are still written for reproducibility. |
ValueError
|
If recursive inputs contain duplicate record identifiers. |
Example
from src.ecg_sqi_inference.models import get_predictor summary = predict_records( ... input_path=Path("record.npy"), ... out_dir=Path("predictions"), ... fs=125, ... predictor=get_predictor("singlelead-rbfsvm"), ... )
Source code in src/ecg_sqi_inference/core.py
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | |
Predictor implementations¶
src.ecg_sqi_inference.models.Conformer12Predictor
dataclass
¶
Load and run the frozen 12-lead Conformer checkpoint.
Attributes:
| Name | Type | Description |
|---|---|---|
ckpt_dir |
Path
|
Directory containing |
device |
str
|
Requested Torch device, |
name |
str
|
Stable public model identifier. |
n_leads |
int
|
Required ECG lead count. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If the checkpoint is absent. |
ValueError
|
If normalization metadata are absent or incompatible. |
Source code in src/ecg_sqi_inference/models.py
predict ¶
Classify 12-lead ECG segments with the Conformer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
segments
|
ndarray
|
Float-compatible array shaped |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
Class labels and binary probabilities for each segment. |
Example
output = predictor.predict(np.zeros((1, 1250, 12), dtype=np.float32)) output.shape[0] 1
Source code in src/ecg_sqi_inference/models.py
src.ecg_sqi_inference.models.Conformer1Predictor
dataclass
¶
Load and run the frozen single-lead BUT Conformer.
Attributes:
| Name | Type | Description |
|---|---|---|
bundle_dir |
Path
|
Directory containing the runtime profile. |
device |
str
|
Requested Torch device, |
name |
str
|
Stable public model identifier. |
n_leads |
int
|
Required ECG lead count. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If the profile or referenced checkpoint is absent. |
ValueError
|
If the checkpoint state is incompatible with the model. |
Source code in src/ecg_sqi_inference/models.py
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | |
predict ¶
Classify single-lead ECG segments as good, medium, or bad.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
segments
|
ndarray
|
Float-compatible array shaped |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
Class labels and three-class probabilities for each segment. |
Example
output = predictor.predict(np.zeros((1, 1250, 1), dtype=np.float32)) output.shape[0] 1
Source code in src/ecg_sqi_inference/models.py
src.ecg_sqi_inference.models.RBFSVMBundlePredictor
dataclass
¶
Run a packaged binary or three-class RBF-SVM.
Attributes:
| Name | Type | Description |
|---|---|---|
bundle_dir |
Path
|
Directory containing |
name |
str
|
Stable public model identifier. |
n_leads |
int
|
Required ECG lead count. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If a bundle file is absent. |
ValueError
|
If the serialized estimator is incompatible with its profile. |
Source code in src/ecg_sqi_inference/models.py
predict ¶
Classify ECG segments using profile-compatible SQI features.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
segments
|
ndarray
|
Float-compatible array shaped |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
One class label and probability row per segment. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If required 12-lead QRS executables are unavailable. |
Example
output = predictor.predict(np.zeros((1, 1250, predictor.n_leads))) output.shape[0] 1
Source code in src/ecg_sqi_inference/models.py
src.ecg_sqi_inference.models.get_predictor ¶
Construct a named predictor from the repository's inference assets.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
Supported public model identifier. |
required |
device
|
str
|
Requested Conformer device, |
'cpu'
|
Returns:
| Type | Description |
|---|---|
Any
|
Initialized predictor for the requested model. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the model identifier is unknown. |
FileNotFoundError
|
If a required checkpoint or bundle file is absent. |
Example
predictor = get_predictor("singlelead-rbfsvm") (predictor.name, predictor.n_leads) ('singlelead-rbfsvm', 1)
Source code in src/ecg_sqi_inference/models.py
src.ecg_sqi_inference.models.verify_inference_bundles ¶
Verify every shipped inference artifact against its frozen SHA-256.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Validation summary containing the verified model names and artifacts. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If the manifest, profile, or model artifact is absent. |
ValueError
|
If an artifact hash does not match the manifest. |
Example
verify_inference_bundles()["status"] 'ok'
Source code in src/ecg_sqi_inference/models.py
src.ecg_sqi_inference.models.feature_frame ¶
Compute the profile-compatible SQI feature table for ECG segments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
segments
|
ndarray
|
ECG array shaped batch, samples, and leads. |
required |
n_leads
|
int
|
Feature pipeline lead count, either 1 or 12. |
required |
profile
|
dict[str, Any]
|
Bundle profile containing normalization statistics. |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
One normalized SQI feature row per segment. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If required 12-lead QRS executables are unavailable. |
Example
feature_frame is normally called by RBFSVMBundlePredictor so
that the bundle profile, feature order, and normalization stay aligned.
Source code in src/ecg_sqi_inference/models.py
Classical pipeline orchestration¶
src.sqi_pipeline.config.SQIPipelineConfig
dataclass
¶
Resolved configuration for one classical SQI pipeline run.
Attributes:
| Name | Type | Description |
|---|---|---|
root |
Path
|
Repository root used for all relative paths. |
artifacts_dir |
Path
|
Directory receiving generated pipeline outputs. |
profile |
str
|
Ordered stage profile, |
seed |
int
|
Frozen random seed used by split and model stages. |
verbose |
bool
|
Whether stages should emit verbose diagnostics. |
force |
bool
|
Whether reusable stage outputs should be regenerated. |
Source code in src/sqi_pipeline/config.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | |
build
classmethod
¶
build(*, artifacts_dir: str | Path = 'outputs/sqi', profile: str = 'baseline', seed: int = 0, verbose: bool = False, force: bool = False) -> 'SQIPipelineConfig'
Build a repository-relative pipeline configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artifacts_dir
|
str | Path
|
Absolute output path or path relative to the repository. |
'outputs/sqi'
|
profile
|
str
|
Stage profile, |
'baseline'
|
seed
|
int
|
Random seed recorded in generated artifacts. |
0
|
verbose
|
bool
|
Enable verbose stage logging. |
False
|
force
|
bool
|
Force stages to regenerate reusable outputs. |
False
|
Returns:
| Type | Description |
|---|---|
'SQIPipelineConfig'
|
Fully resolved immutable configuration. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Example
cfg = SQIPipelineConfig.build(profile="paper_aligned", seed=0) cfg.artifacts_dir.is_absolute() True
Source code in src/sqi_pipeline/config.py
base_params ¶
Return parameters shared by every stage in the selected profile.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
JSON-compatible scalar settings and repository-resolved paths. |
Source code in src/sqi_pipeline/config.py
src.sqi_pipeline.runner.StepSpec
dataclass
¶
Import contract for one ordered classical pipeline stage.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Stable stage name accepted by the CLI |
module |
str
|
Import path containing the stage callable. |
func |
str
|
Callable name; stages use |
Source code in src/sqi_pipeline/runner.py
src.sqi_pipeline.runner.steps_for_profile ¶
Return the ordered stage contract for a classical pipeline profile.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
profile
|
str
|
|
required |
Returns:
| Type | Description |
|---|---|
tuple[StepSpec, ...]
|
Immutable ordered stage specifications. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the profile is unknown. |
Source code in src/sqi_pipeline/runner.py
src.sqi_pipeline.runner.run_pipeline ¶
Execute selected stages and collect a portable run summary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cfg
|
SQIPipelineConfig
|
Resolved classical pipeline configuration. |
required |
only
|
list[str] | None
|
Optional stage-name subset. Omitted dependencies must already
exist below |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Summary containing profile metadata, stage outputs, reuse state, and |
dict[str, Any]
|
duration. Output paths are repository-relative where possible. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a requested stage is not part of the selected profile. |
TypeError
|
If a stage violates the required dictionary return contract. |
Example
cfg = SQIPipelineConfig.build(profile="baseline") summary = run_pipeline(cfg, only=["manifest_raw"])
Source code in src/sqi_pipeline/runner.py
For end-user invocation, prefer the CLI. The Python orchestration interface is intended for controlled programmatic runs.