ECG2DCM
Convert resting 12-lead ECG recordings to DICOM General ECG Waveform Storage objects: GE MUSE XML first, and also GE CardioSoft, Philips Sierra, HL7 aECG, Mortara ELI Link, Schiller SEMA and WFDB.
This is the implementation reported in ECG2DCM: An open-source framework for converting resting 12-lead electrocardiograms to DICOM waveform objects. Release v1.3.0 produced the results in that paper; v1.3.1 differs only in two code-meaning strings and in the documentation. MIT License.
pip install ecg2dcm # add [philips] for Philips Sierra files, [validate] for dicom-validator
ecg2dcm-convert examples/synthetic_muse.xml -o out/
What it writes
One DICOM object per recording, with
- the rhythm strip and the median (representative) beat as two multiplex groups of twelve channels, the four limb leads derived from I and II and marked as such with Channel Derivation Description (003A,020C);
- channel sources coded from CID 3001 "ECG Lead" (ISO/IEEE 11073-10101), units from UCUM, the acquisition context from TID 3401, filter settings in hertz with the pass-band edges on the right attributes;
- the global measurements (rates, PR, QRS, QT, QTc, P/QRS/T axes) as coded Waveform Annotations from TID 3713 and CID 3229, with the PR, QRS and QT intervals and the P wave also carried as sample-position segments on the median beat.
docs/mapping/attribute_mapping.csv lists every attribute with its source
element and mapping strategy; docs/mapping/coded_values.csv lists every code
with its governing context group. docs/conformance.md explains why the
General ECG IOD is used (the 12-Lead ECG IOD allows at most 13 channels across
all groups) and what the two levels of validation do and do not check.
De-identification
On by default. Names and site identifiers become Anonymized, the patient ID
becomes a per-run surrogate, dates keep year and month with the day set to 01,
times become 00:00:00, and the birth date and free-text interpretation are
dropped. See docs/deidentification.md. Pass --keep-identity to write the
source values.
Commands
ecg2dcm-convert converts any supported file or directory, detecting the
format from the content:
ecg2dcm-convert path/to/files -o out/ --recursive [--uid-root 1.2.3.4] [--keep-identity]
ecg2dcm is the batch command used for the study corpus. It walks a
directory of GE MUSE XML files, names each output from a regular expression on
the input file name, and writes the surrogate-ID table next to the output:
ecg2dcm --project_root . --data_root /data --ecg_xml_dir muse_xml --output_dir ecg_dcm \
--filename_pattern "MUSE_(?P<examination_date>\d{8})_(?P<examination_time>\d{6})_(?P<seq>\d{5})" \
--out_filename_pattern "ECG_DICOM_{examination_date}_{seq}"
--out_filename_pattern must contain exactly one {...date...} key and should
contain {seq} (appended automatically otherwise).
UID root. Study, Series and SOP Instance UIDs are issued under --uid-root.
The default is pydicom's registered root, a placeholder; issue UIDs under your
organisation's own OID before production use.
Python API
from ecg2dcm import parse, build, write, check_iod_constraints
rec = parse('record.xml') # any supported format -> EcgRecord
ds = build(rec, index=1) # pydicom FileDataset, de-identified
assert check_iod_constraints(ds) == [] # General ECG IOD content constraints
ds.save_as('record.dcm', write_like_original=False)
Each front end lives in ecg2dcm/adapters/ and produces the same intermediate
representation (ecg2dcm/ir.py); ecg2dcm/writer.py is the only place DICOM
is written.
Reproducing the paper
analysis/ holds the scripts behind the reported tables. They read the
institution's export archive or the public PhysioNet mirrors and write only
aggregate tables.
| Script | Result |
|---|---|
supp_table9_device_profile.py |
device and software profile of the corpus (Supplementary Table 9, part 1) |
stratified_conversion.py |
whole-corpus conversion, attribute-level validation, required-attribute completeness and IOD content constraints, stratified by device and software (Supplementary Table 9, part 2) |
coverage_matrix.py, wfdb_header_coverage.py |
attribute coverage by source format (Supplementary Table 10) |
run_wfdb.py |
five open WFDB datasets, as distributed and with the acquisition instant supplied |
ecg_cxr_pairing.py |
ECG and chest radiograph pairing in MIMIC-IV-ECG and MIMIC-CXR |
Validation uses dicom-validator against the 2024b edition of the standard
(pip install "ecg2dcm[validate]", then dicom-validator downloads the edition).
Examples and tests
examples/ contains a synthetic GE MUSE file (generated by
make_synthetic_muse.py; nothing in it comes from a patient) and one publicly
released, MIT-licensed teaching file, each with its converted DICOM object; see
examples/ATTRIBUTION.md. pytest tests converts both and checks the objects.
History
Formerly distributed as XML2DCM-ECG (last version 1.1.10); that name is
unmaintained. CHANGELOG.md lists what changed in each release, including the
corrections made during peer review.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ecg2dcm-1.3.1.tar.gz.
File metadata
- Download URL: ecg2dcm-1.3.1.tar.gz
- Upload date:
- Size: 342.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dec870a883646a6039c89e07e9df8bef43349cfc6fc329c3cb4f58845b6b74ee
|
|
| MD5 |
c7fb539a37c89110ac944211b0cd371d
|
|
| BLAKE2b-256 |
a537e3a4637121e8d2b4f680e93b47325091df2439c06d50aa2ab3bdb24ae448
|
Provenance
The following attestation bundles were made for ecg2dcm-1.3.1.tar.gz:
Publisher:
publish.yml on HyeonhoonLee/ecg2dcm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ecg2dcm-1.3.1.tar.gz -
Subject digest:
dec870a883646a6039c89e07e9df8bef43349cfc6fc329c3cb4f58845b6b74ee - Sigstore transparency entry: 2796582704
- Sigstore integration time:
-
Permalink:
HyeonhoonLee/ecg2dcm@6b8ef45135cd3a709ee5ee951c98edaac225b99a -
Branch / Tag:
refs/tags/v1.3.1 - Owner: https://github.com/HyeonhoonLee
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6b8ef45135cd3a709ee5ee951c98edaac225b99a -
Trigger Event:
release
-
Statement type:
File details
Details for the file ecg2dcm-1.3.1-py3-none-any.whl.
File metadata
- Download URL: ecg2dcm-1.3.1-py3-none-any.whl
- Upload date:
- Size: 40.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cfee6ad899201d3da3cf687413691755a2843175d0870bbfd35a31d884611c14
|
|
| MD5 |
25e92e2b1e5e02f9e8b7c04e715e4580
|
|
| BLAKE2b-256 |
8c08c8372c32053f797aca1b4fa1beb4ba3859e325929dd0ea83ee999e573ab6
|
Provenance
The following attestation bundles were made for ecg2dcm-1.3.1-py3-none-any.whl:
Publisher:
publish.yml on HyeonhoonLee/ecg2dcm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ecg2dcm-1.3.1-py3-none-any.whl -
Subject digest:
cfee6ad899201d3da3cf687413691755a2843175d0870bbfd35a31d884611c14 - Sigstore transparency entry: 2796582724
- Sigstore integration time:
-
Permalink:
HyeonhoonLee/ecg2dcm@6b8ef45135cd3a709ee5ee951c98edaac225b99a -
Branch / Tag:
refs/tags/v1.3.1 - Owner: https://github.com/HyeonhoonLee
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6b8ef45135cd3a709ee5ee951c98edaac225b99a -
Trigger Event:
release
-
Statement type: