Releases¶
All published releases of ECGDataKit, fetched from GitHub Releases at build time.
v2.0.3 - XLE 12 leads and format detection¶
Released 2026-10-14 · View on GitHub
ECGDataKit 2.0.3¶
XLE (experimental):
XLEParser(wilson_correction=True, compute_missing_leads=True)gives the standard 12 leads. III, aVR, aVL and aVF are computed from I and II, with a warning. The option requires the Wilson correction.New
FileParser.detect_format(path): tells the format of a file and the parser that reads it, without parsing it.FileParser.parse(path)no longer needs an instance.FileParser().parse(path)still works.
Full Changelog: https://github.com/UMMISCO/ECGDataKit/compare/v2.0.2…v2.0.3
v2.0.2 - XLE voltage scale, chest leads and recording date¶
Released 2026-10-14 · View on GitHub
ECGDataKit 2.0.2¶
Updates to the experimental XLE parser.
Samples are now converted to mV with a scale of 0.9375 µV per count. The file does not store this scale and the manufacturer has not validated it, so the conversion issues a warning.
Leads are named I, II and CR1 to CR6, since the chest leads are stored against the right arm. An optional Wilson correction,
XLEParser(wilson_correction=True), turns them into V1 to V6, with a warning.The recording date and time are now read from the file.
XLE support remains experimental. Check amplitudes against the recorder’s own printout before use.
Full Changelog: https://github.com/UMMISCO/ECGDataKit/compare/v2.0.1…v2.0.2
v2.0.1¶
Released 2026-10-13 · View on GitHub
ECGDataKit 2.0.1¶
This release adds a new ECG format.
Parsing¶
New format (experimental): XLE ECG (
.xle). 8-channel ECG recordings can now be read. The format is not documented, so its layout was worked out from sample files. The files do not state the voltage scale, so signals are kept in raw values and never converted with a guessed factor.
Anonymization¶
XLE files can now be anonymized like the other formats.
Full Changelog: https://github.com/UMMISCO/ECGDataKit/compare/v2.0.0…v2.0.1
v2.0.0 - New anonymization module¶
Released 2026-10-12 · View on GitHub
ECGDataKit 2.0.0¶
This release adds anonymization of ECG files, for every format ECGDataKit reads.
Anonymization¶
New
ecgdatakit.anonymizemodule with a command line tool (ecgdatakit anonymize). Anonymizes ECG files by replacing the patient’s identity (patient names, patient ID and ECG ID) with pseudonyms.All supported formats. Every format ECGDataKit reads can be anonymized, except EDAN Holter. Each anonymized file is checked to hold the same signal as the original.
Patients and folders. Files can be grouped by patient folder, so all the recordings of a patient share one pseudonym. Patient folders can also be renamed.
Catalog and checks. A CSV catalog links each original file to its anonymized copy and flags the files to review.
Continuous mode. The anonymizer can run in the background and handle new files as they arrive, also in a Docker container.
Documentation¶
The documentation has a new layout and new pages on anonymization.
Full documentation: https://ecgdatakit.ummisco.fr
Full Changelog: https://github.com/UMMISCO/ECGDataKit/compare/v1.1.1…v2.0.0
v1.1.1¶
Released 2026-10-09 · View on GitHub
New format: AliveCor Kardia JSON¶
ECG recordings exported from the Kardia API (KardiaMobile and KardiaMobile 6L) can now be read.
The unfiltered signal goes to
leads. The signal filtered by AliveCor goes to a newleads_enhancedfield. Other formats leave this field empty.Samples are scaled with
amplitudeResolution(nanovolts per count), as described in the Kardia API documentation.The AliveCor algorithm result (for example
afib) is reported as a machine interpretation.Kardia 12L recordings use a different layout and are not supported.
ECGDataKit now reads 12 formats.
Detected format and parser in file_format¶
record.file_format now holds the name of the detected format (name) and the parser that read the file (parser). They are filled in when the file is read through FileParser or parse_batch.
Annotation changes¶
These changes rename or remove annotation keys. Code that reads them may need updating.
No more repeated measurements. The Sierra and Mortara parsers stored some values both in
measurementsand inannotations. A value with a measurement field is now stored only inmeasurements. All other values stay inannotations.One key per wave boundary. HL7 aECG and SCP-ECG wrote all wave boundaries into one text annotation,
wave_boundaries_ms. Each boundary now has its own key.Representative beat boundaries start with
median_in every parser, for examplemedian_p_onset_msormedian_q_onset. This covers HL7 aECG, SCP-ECG, Mortara, GE MUSE and Sierra.Keys end with their unit when the format states it:
_ms,_samplesor_s.DICOM time-referenced annotations moved from
raw_metadata["waveform_annotations"]toannotations, with one key per wave type, for examplep_onset_samples.
Full Changelog: https://github.com/UMMISCO/ECGDataKit/compare/v1.1.0…v1.1.1
v1.1.0¶
Released 2026-10-09 · View on GitHub
Breaking changes¶
Only stored values are reported: intervals, heart rate, QTc, end dates and derived leads are no longer computed, and pacemaker status or severity are no longer inferred from text. Missing fields stay empty.
Stricter error handling: unknown files raise
UnsupportedFormatError, empty or damaged files raiseCorruptedFileError, and a missing optional dependency raisesImportError.Processing input validation: NaN, infinite values and 2-D arrays raise
ValueError.clean_ecgrejects unknown keyword arguments and propagates backend errors.Normalized leads are unitless: min-max and z-score outputs carry no physical unit and are not rescaled by
to_physical().Lead.to_physical()raisesRawSamplesErrorwhen the file provides no physical unit.
Parsing¶
Scaling contract:
FileParser.parse()returns leads in mV by default.auto_scale=Falsereturns the stored values together with the scale needed to convert them.Interpretation source:
interpretation.sourcedistinguishes device statements ("machine") from physician statements ("confirmed","overread"). When both are present, the device statements are kept inannotations["machine_interpretation"].SCP-ECG and MFER rewritten according to EN 1064 and MFER Part 1.
WFDB, EDF, DICOM, HL7 aECG, GE MUSE, Philips Sierra, Mortara ELI and ISHNE: numerous decoding and metadata fixes. Decoded signals match wfdb-python, pyedflib, pydicom, the FDA aECG reader and sierraecg on real recordings.
EDAN ARC Holter marked experimental, as the format is undocumented.
New fields:
ECGRecord.file_format,PatientInfo.has_pacemakerandPatientInfo.pacemaker_type. NewChecksumWarningfor checksum mismatches.
Signal processing¶
R-peak detection: Pan-Tompkins (default) no longer stops after artifacts, ignores flat segments and no longer counts T waves. MIT-BIH: 99.5 % sensitivity, 98.1 % positive predictive value at 250 to 1000 Hz.
Lead derivation, resamplingw and physical leads correctly.
Signal quality and HRV are consistent across sampling rates, and warn on recordings too short for frequency-domain
DeepFADE preserves input amplitude, refuses raw counts and is marked experimental.
Full Changelog: https://github.com/UMMISCO/ECGDataKit/compare/v1.0.2…v1.1.0
v1.0.2¶
Released 2026-07-06 · View on GitHub
Full Changelog: https://github.com/UMMISCO/ECGDataKit/compare/v1.0.0…v1.0.2
v1.0.0 - Stable Release¶
Released 2026-03-19 · View on GitHub
New features¶
Per-lead normalization —
normalize_minmax,normalize_zscore, andnormalize_amplitudenow accept alist[Lead]and return alist[Lead], normalizing each lead independently. Passrecord.leadsdirectly instead of looping manuallyResampling and normalization (min-max, z-score, amplitude) now support batch processing across all leads (independently) of an ECG record
Full Changelog: https://github.com/UMMISCO/ECGDataKit/compare/v0.0.9…v1.0.0
v0.0.9 - ADC resolution pipeline¶
Released 2026-03-07 · View on GitHub
Breaking changes¶
sample_raterenamed tosampling_rateinLeadandSignalCharacteristicsLead.unitssemantics changed — now empty ("") whenis_raw=True(raw ADC counts); set to the physical unit (voltages) only afterto_physical()or when data is already in physical unitsLead.is_rawis now auto-detected — parsers no longer hardcodeis_raw=True; insteadis_raw = not (resolution == 1.0 and offset == 0.0)
New features¶
Automatic ADC-to-physical scaling —
FileParser.parse(auto_scale=True)(default) converts raw ADC samples to mV viato_physical()+convert_units("mV"). Disable withauto_scale=FalseLead.to_physical()— converts raw ADC samples usingphysical = samples × resolution + offsetLead.convert_units(target)— converts between voltage units (uV, mV, V)ECGRecord.to_physical()/ECGRecord.convert_units(target)— batch conversion for all leads and median beatsFileParser.supported_formats()— returns format metadata for all 12 parsersECGRecord.__repr__()andECGRecord.plot()— YAML-style console display and quick plottingMulti-lead numpy array support —
plot_leads,plot_12lead,iplot_leads,iplot_12leadaccept raw numpy arrays withfs=parameterLeadsLiketype alias — for multi-lead inputs (list of Lead, ECGRecord, 2D array, list of arrays)
New Lead fields¶
resolution_unit— unit of the resolution scale factor (e.g."uV","mV"); what samples will be in afterto_physical()adc_resolution— original ADC resolution as stored in the source file (e.g.153.0for 153 nV/count in ISHNE)adc_resolution_unit— unit ofadc_resolutionas defined by the format (e.g."nV"for ISHNE and SCP-ECG)
Improvements¶
Simplified multi-lead plots: full signal by default with configurable
rows/colsgrid layoutplot_12leadandiplot_12leadassign standard 12-lead names to unnamed inputsStatic plots no longer force matplotlib Agg backend
Full Changelog: https://github.com/UMMISCO/ECGDataKit/commits/v0.0.9
v0.0.8 - Visualization¶
Released 2026-03-03 · View on GitHub
Visualization¶
Multi-lead plotting functions (
plot_leads,plot_12lead,plot_quality,iplot_leads,iplot_12lead) now accept raw numpy arrays directly withfs=parameter — pass a 2D array (n_leads × n_samples) or a list of 1D arrays alongside the sample rateNew
LeadsLiketype alias for multi-lead inputs:list[Lead] | ECGRecord | NDArray | list[NDArray]Static plots no longer force the
Aggbackend — plots display inline in Jupyter and GUI environments by default
Full Changelog: https://github.com/UMMISCO/ECGDataKit/commits/v0.0.8
v0.0.7 - Signal Characteristics, Flexible Inputs & Sphinx Docs¶
Released 2026-03-02 · View on GitHub
What’s New¶
Signal Characteristics Model¶
New SignalCharacteristics dataclass on every ECGRecord — captures technical signal encoding metadata directly from each format:
bits_per_sample,signal_offset,signal_signeddata_encoding(e.g.base64_int16le,format_212,int16)compression(e.g.none,huffman)number_channels_allocated/number_channels_validelectrode_placement,acsetting, and signal processing flags
All 12 parsers now populate record.signal from format-specific fields.
Expanded Metadata Extraction¶
Parsers now extract significantly more metadata from each format:
Technician — Sierra XML, GE MUSE, DICOM, GE MAC 2000
Referring physician — Sierra XML, EDF, GE MUSE, GE MAC 2000
Patient weight — SCP-ECG (Tag 12), BeneHeart R12, GE MAC 2000
Patient height — BeneHeart R12, GE MAC 2000
Patient race — HL7 aECG, Mortara EL250, GE MAC 2000
RR interval & QRS count — Mortara EL250, BeneHeart R12, GE MAC 2000
Device serial number — HL7 aECG, GE MAC 2000
Notch filter active flag — now properly set across all parsers
Flexible Inputs — Numpy Arrays Everywhere¶
All processing and plotting functions now accept raw numpy arrays directly alongside Lead objects. Pass the sample rate via fs=:
import numpy as np
from ecgdatakit.processing import diagnostic_filter, detect_r_peaks
from ecgdatakit.plotting import plot_lead
signal = np.random.randn(5000)
filtered = diagnostic_filter(signal, fs=500)
peaks = detect_r_peaks(filtered)
plot_lead(filtered, peaks=peaks)
Plotting Improvements¶
Auto-display: static plots now call plt.show() by default — pass show=False to get the figure for saving
Sample index axis: plot_lead(lead, x_axis=”samples”) for sample indices instead of time
Cleaner layout: reduced margins, integer time ticks on x-axis
Documentation Migration¶
Migrated from Hugo to Sphinx with the Furo theme
Full autodoc API reference generated from source docstrings
Hosted at https://ecgdatakit.ummisco.fr
Bug Fixes
BeneHeart R12: fixed assignment to non-existent RecordingInfo.device field
SCP-ECG: now reads patient weight from Tag 12 (was silently skipped)
MFER: notch filter now correctly extracted from filter tag when 12+ bytes present
Full Changelog: https://github.com/UMMISCO/ECGDataKit/commits/v0.0.0.7