ECGProcess 1.1.0__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ecgprocess-1.2.0/ECGProcess.egg-info/PKG-INFO +224 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ECGProcess.egg-info/SOURCES.txt +14 -1
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ECGProcess.egg-info/requires.txt +11 -2
- ecgprocess-1.2.0/PKG-INFO +224 -0
- ecgprocess-1.2.0/README.md +170 -0
- ecgprocess-1.2.0/ecgprocess/__init__.py +34 -0
- ecgprocess-1.2.0/ecgprocess/_version.py +1 -0
- ecgprocess-1.2.0/ecgprocess/constants.py +315 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/errors.py +191 -14
- ecgprocess-1.2.0/ecgprocess/example_data/example_datasets/example-XMLWriter1.json +31 -0
- ecgprocess-1.2.0/ecgprocess/example_data/example_datasets/example-XMLWriter1.xsd +27 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/examples.py +60 -10
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/plot_ecgs.py +189 -21
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/process_dicom.py +5 -21
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/process_xml.py +93 -43
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/tabular.py +404 -532
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/utils/config_tools.py +56 -45
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/utils/ecg_tools.py +33 -32
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/utils/engineering_tools.py +28 -12
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/utils/general.py +53 -23
- ecgprocess-1.2.0/ecgprocess/writer/__init__.py +69 -0
- ecgprocess-1.2.0/ecgprocess/writer/writer_base.py +670 -0
- ecgprocess-1.2.0/ecgprocess/writer/writer_figure.py +302 -0
- ecgprocess-1.2.0/ecgprocess/writer/writer_numpy.py +247 -0
- ecgprocess-1.2.0/ecgprocess/writer/writer_pixel.py +295 -0
- ecgprocess-1.2.0/ecgprocess/writer/writer_table.py +334 -0
- ecgprocess-1.2.0/ecgprocess/writer/writer_tfrecord.py +144 -0
- ecgprocess-1.2.0/ecgprocess/writer/writer_wfdb.py +291 -0
- ecgprocess-1.2.0/ecgprocess/writer/writer_xml.py +572 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/pyproject.toml +16 -2
- ecgprocess-1.2.0/requirements-tensorflow.txt +1 -0
- ecgprocess-1.2.0/requirements-wfdb.txt +1 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/requirements.txt +1 -2
- ecgprocess-1.1.0/ECGProcess.egg-info/PKG-INFO +0 -153
- ecgprocess-1.1.0/PKG-INFO +0 -153
- ecgprocess-1.1.0/README.md +0 -105
- ecgprocess-1.1.0/ecgprocess/__init__.py +0 -1
- ecgprocess-1.1.0/ecgprocess/_version.py +0 -1
- ecgprocess-1.1.0/ecgprocess/constants.py +0 -170
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ECGProcess.egg-info/dependency_links.txt +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ECGProcess.egg-info/top_level.txt +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/LICENCE.txt +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/__init__.py +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/.example-XML1.xml.un~ +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/.example-XML1.xsd.un~ +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/.example-XML1_a.xsd.un~ +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/.example-XML1_d.xsd.un~ +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/.example-XML1_wrong.xsd.un~ +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/example-DICOM1.dcm +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/example-DICOM2.dcm +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/example-XML1.xml +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/example-XML1.xsd +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/example-XML1_error.xsd +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/example-XML1_wrong.xsd +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/string_data.txt +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/utils/__init__.py +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/utils/reader_tools.py +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/requirements-dev.txt +0 -0
- {ecgprocess-1.1.0 → ecgprocess-1.2.0}/setup.cfg +0 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ECGProcess
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: A python module to process and standardise ECG data
|
|
5
|
+
Author-email: "A. Floriaan Schmidt" <floriaanschmidt@gmail.com>
|
|
6
|
+
License-Expression: GPL-3.0-or-later
|
|
7
|
+
Project-URL: Homepage, https://gitlab.com/SchmidtAF/ECGProcess
|
|
8
|
+
Project-URL: Documentation, https://SchmidtAF.gitlab.io/ECGProcess/
|
|
9
|
+
Classifier: Programming Language :: Python
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
15
|
+
Requires-Python: <3.14,>=3.11
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENCE.txt
|
|
18
|
+
Requires-Dist: lxml>=5
|
|
19
|
+
Requires-Dist: xmltodict>=1.0.3
|
|
20
|
+
Requires-Dist: pandas>=2.1.1
|
|
21
|
+
Requires-Dist: numpy>=1.26
|
|
22
|
+
Requires-Dist: scipy>=1.7
|
|
23
|
+
Requires-Dist: pydicom>=2
|
|
24
|
+
Requires-Dist: matplotlib>=3.9
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest>=6; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-mock>=3.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-dependency>=0.5; extra == "dev"
|
|
29
|
+
Requires-Dist: codespell; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff; extra == "dev"
|
|
31
|
+
Requires-Dist: bump2version>=1; extra == "dev"
|
|
32
|
+
Requires-Dist: build; extra == "dev"
|
|
33
|
+
Requires-Dist: twine; extra == "dev"
|
|
34
|
+
Requires-Dist: sphinx; extra == "dev"
|
|
35
|
+
Requires-Dist: sphinx-rtd-theme; extra == "dev"
|
|
36
|
+
Requires-Dist: sphinx-bootstrap-theme; extra == "dev"
|
|
37
|
+
Requires-Dist: furo; extra == "dev"
|
|
38
|
+
Requires-Dist: myst-parser; extra == "dev"
|
|
39
|
+
Requires-Dist: nbsphinx; extra == "dev"
|
|
40
|
+
Requires-Dist: nbsphinx-link; extra == "dev"
|
|
41
|
+
Requires-Dist: sphinx-argparse; extra == "dev"
|
|
42
|
+
Requires-Dist: numpydoc; extra == "dev"
|
|
43
|
+
Requires-Dist: docutils<0.21; extra == "dev"
|
|
44
|
+
Requires-Dist: notebook; extra == "dev"
|
|
45
|
+
Requires-Dist: jupyter; extra == "dev"
|
|
46
|
+
Provides-Extra: tensorflow
|
|
47
|
+
Requires-Dist: tensorflow>=2.16; extra == "tensorflow"
|
|
48
|
+
Provides-Extra: wfdb
|
|
49
|
+
Requires-Dist: wfdb<5,>=4.3.1; extra == "wfdb"
|
|
50
|
+
Provides-Extra: all
|
|
51
|
+
Requires-Dist: tensorflow>=2.16; extra == "all"
|
|
52
|
+
Requires-Dist: wfdb<5,>=4.3.1; extra == "all"
|
|
53
|
+
Dynamic: license-file
|
|
54
|
+
|
|
55
|
+
<!-- TODO once dev is merged into master and the pages job redeploys, switch
|
|
56
|
+
this back to the Sphinx-published URL:
|
|
57
|
+
https://SchmidtAF.gitlab.io/ECGProcess/_static/ecgp_logo.png -->
|
|
58
|
+
<img src="https://gitlab.com/SchmidtAF/ECGProcess/-/raw/d853ccf/docs/source/_static/ecgp_logo.png" alt="ECGProcess icon" width="250"/>
|
|
59
|
+
|
|
60
|
+
# An ECG processing module
|
|
61
|
+
__version__: `1.2.0`
|
|
62
|
+
|
|
63
|
+
Supports Python 3.11-3.13; the test suite runs against all three versions
|
|
64
|
+
in CI.
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
This repository hosts a collection of functions for processing
|
|
68
|
+
electrocardiogram (ECG) data and preparing it for analysis.
|
|
69
|
+
|
|
70
|
+
At a glance, ECGProcess is driven by three units:
|
|
71
|
+
|
|
72
|
+
* A **processor** unit, reads individual ECG files and based on
|
|
73
|
+
a user-supplied configuration file extracts waveform
|
|
74
|
+
signals, median beats, and metadata to python dictionaries; see [Configuration files](https://SchmidtAF.gitlab.io/ECGProcess/configuration_files.html)).
|
|
75
|
+
* The **table** unit, `ECGTable`, loops over a directory of ECG files,
|
|
76
|
+
calls the reader for each one, while applying optional engineering steps
|
|
77
|
+
(e.g. resampling, calibration, lead correction), and again optionally
|
|
78
|
+
concatenating multiple files together.
|
|
79
|
+
* A **writer** unit, tells `ECGTable` what to write to disk
|
|
80
|
+
(tables, NumPy arrays, WFDB records, images, ...).
|
|
81
|
+
|
|
82
|
+
Together these units implement an application programming interface (API),
|
|
83
|
+
mapping ECG data from distinct file types to class attributes
|
|
84
|
+
providing a fixed interface for downstream processing.
|
|
85
|
+
The package ships with boilerplate classes and validation utilities,
|
|
86
|
+
letting the user expand **processing** of additional file types,
|
|
87
|
+
build custom **engineering** (e.g. standardisation) pipelines, as well as
|
|
88
|
+
create custom **writers**.
|
|
89
|
+
|
|
90
|
+
Please consult the [documentation](https://SchmidtAF.gitlab.io/ECGProcess/)
|
|
91
|
+
for the full picture.
|
|
92
|
+
|
|
93
|
+
## Installation
|
|
94
|
+
The package is available on PyPI, and conda, with the latest source code
|
|
95
|
+
available on gitlab.
|
|
96
|
+
|
|
97
|
+
### Installation using PyPI
|
|
98
|
+
|
|
99
|
+
To install the package from PyPI, run:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pip install ecgprocess
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
This installs the latest stable release along with its dependencies.
|
|
106
|
+
|
|
107
|
+
### Installation using conda
|
|
108
|
+
|
|
109
|
+
A Conda package is maintained in my personal Conda channel.
|
|
110
|
+
To install from this channel, run:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
conda install afschmidt::ecgprocess
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Installation using gitlab
|
|
117
|
+
|
|
118
|
+
If you require the latest updates, potentially not yet formally released,
|
|
119
|
+
you can install the package directly from GitLab.
|
|
120
|
+
|
|
121
|
+
First, clone the repository and move into its root directory:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
git clone git@gitlab.com:SchmidtAF/ecgprocess.git
|
|
125
|
+
cd ecgprocess
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Install the dependencies:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# From the root of the repository
|
|
132
|
+
conda env create --file ./resources/conda/envs/conda_create.yaml
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
To add to an existing environment use:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# From the root of the repository
|
|
139
|
+
conda env update --file ./resources/conda/envs/conda_update.yaml
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Next the package can be installed:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
make install
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### Development
|
|
149
|
+
For development work, install the package in editable mode, with its
|
|
150
|
+
development dependencies (`pytest`, `codespell`, `sphinx`, ...) and Git
|
|
151
|
+
commit hooks configured:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
make install-dev
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
This command installs the package in editable mode with the `[dev]`
|
|
158
|
+
extras and configures Git commit hooks, allowing you to run `git pull`
|
|
159
|
+
to update the repository or switch branches without reinstalling.
|
|
160
|
+
|
|
161
|
+
Alternatively, you can install manually. This is exactly equivalent
|
|
162
|
+
to `make install-dev`:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
python -m pip install -e ".[dev]"
|
|
166
|
+
python .githooks/.setup_git_hooks.py
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Git Hooks Configuration
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
When setting up a development environment, the `setup-hooks` command
|
|
173
|
+
configures Git hooks to enforce conventional commit message formatting and
|
|
174
|
+
spell check using `codespell`.
|
|
175
|
+
|
|
176
|
+
To view the commit message format requirements, run:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
./.githooks/commit-msg -help
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
For frequent use, add this function to your shell configuration (`~/.bashrc`
|
|
183
|
+
or `~/.zshrc`):
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
commit-format-help() {
|
|
187
|
+
local git_root
|
|
188
|
+
git_root=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
189
|
+
|
|
190
|
+
if [ -z "$git_root" ]; then
|
|
191
|
+
echo "Error: Not inside a git repository"
|
|
192
|
+
return 1
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
local hook_path="$git_root/.githooks/commit-msg"
|
|
196
|
+
|
|
197
|
+
if [ ! -f "$hook_path" ]; then
|
|
198
|
+
echo "Error: commit-msg hook not found"
|
|
199
|
+
return 1
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
"$hook_path" --help
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Next steps...
|
|
207
|
+
If you installed with `make install-dev`, you might wish to run `pytest` to
|
|
208
|
+
confirm everything is in working order.
|
|
209
|
+
|
|
210
|
+
```sh
|
|
211
|
+
# From the root of the repository
|
|
212
|
+
pytest tests
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Usage
|
|
216
|
+
|
|
217
|
+
Please have a look at the [example](https://SchmidtAF.gitlab.io/ECGProcess/examples.html)
|
|
218
|
+
recipes.
|
|
219
|
+
|
|
220
|
+
## Icon
|
|
221
|
+
|
|
222
|
+
The package icon features the Etruscan shrew, one of the smallest
|
|
223
|
+
mammals, whose heart can beat over 1,500 times a minute, the fastest
|
|
224
|
+
heart rate of any mammal.
|
|
@@ -2,6 +2,8 @@ LICENCE.txt
|
|
|
2
2
|
README.md
|
|
3
3
|
pyproject.toml
|
|
4
4
|
requirements-dev.txt
|
|
5
|
+
requirements-tensorflow.txt
|
|
6
|
+
requirements-wfdb.txt
|
|
5
7
|
requirements.txt
|
|
6
8
|
ECGProcess.egg-info/PKG-INFO
|
|
7
9
|
ECGProcess.egg-info/SOURCES.txt
|
|
@@ -29,10 +31,21 @@ ecgprocess/example_data/example_datasets/example-XML1.xml
|
|
|
29
31
|
ecgprocess/example_data/example_datasets/example-XML1.xsd
|
|
30
32
|
ecgprocess/example_data/example_datasets/example-XML1_error.xsd
|
|
31
33
|
ecgprocess/example_data/example_datasets/example-XML1_wrong.xsd
|
|
34
|
+
ecgprocess/example_data/example_datasets/example-XMLWriter1.json
|
|
35
|
+
ecgprocess/example_data/example_datasets/example-XMLWriter1.xsd
|
|
32
36
|
ecgprocess/example_data/example_datasets/string_data.txt
|
|
33
37
|
ecgprocess/utils/__init__.py
|
|
34
38
|
ecgprocess/utils/config_tools.py
|
|
35
39
|
ecgprocess/utils/ecg_tools.py
|
|
36
40
|
ecgprocess/utils/engineering_tools.py
|
|
37
41
|
ecgprocess/utils/general.py
|
|
38
|
-
ecgprocess/utils/reader_tools.py
|
|
42
|
+
ecgprocess/utils/reader_tools.py
|
|
43
|
+
ecgprocess/writer/__init__.py
|
|
44
|
+
ecgprocess/writer/writer_base.py
|
|
45
|
+
ecgprocess/writer/writer_figure.py
|
|
46
|
+
ecgprocess/writer/writer_numpy.py
|
|
47
|
+
ecgprocess/writer/writer_pixel.py
|
|
48
|
+
ecgprocess/writer/writer_table.py
|
|
49
|
+
ecgprocess/writer/writer_tfrecord.py
|
|
50
|
+
ecgprocess/writer/writer_wfdb.py
|
|
51
|
+
ecgprocess/writer/writer_xml.py
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
lxml>=5
|
|
2
|
-
xmltodict>=0.
|
|
2
|
+
xmltodict>=1.0.3
|
|
3
3
|
pandas>=2.1.1
|
|
4
4
|
numpy>=1.26
|
|
5
5
|
scipy>=1.7
|
|
6
|
-
tensorflow>=2.16
|
|
7
6
|
pydicom>=2
|
|
8
7
|
matplotlib>=3.9
|
|
9
8
|
|
|
9
|
+
[all]
|
|
10
|
+
tensorflow>=2.16
|
|
11
|
+
wfdb<5,>=4.3.1
|
|
12
|
+
|
|
10
13
|
[dev]
|
|
11
14
|
pytest>=6
|
|
12
15
|
pytest-mock>=3.0
|
|
@@ -28,3 +31,9 @@ numpydoc
|
|
|
28
31
|
docutils<0.21
|
|
29
32
|
notebook
|
|
30
33
|
jupyter
|
|
34
|
+
|
|
35
|
+
[tensorflow]
|
|
36
|
+
tensorflow>=2.16
|
|
37
|
+
|
|
38
|
+
[wfdb]
|
|
39
|
+
wfdb<5,>=4.3.1
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ECGProcess
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: A python module to process and standardise ECG data
|
|
5
|
+
Author-email: "A. Floriaan Schmidt" <floriaanschmidt@gmail.com>
|
|
6
|
+
License-Expression: GPL-3.0-or-later
|
|
7
|
+
Project-URL: Homepage, https://gitlab.com/SchmidtAF/ECGProcess
|
|
8
|
+
Project-URL: Documentation, https://SchmidtAF.gitlab.io/ECGProcess/
|
|
9
|
+
Classifier: Programming Language :: Python
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
15
|
+
Requires-Python: <3.14,>=3.11
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENCE.txt
|
|
18
|
+
Requires-Dist: lxml>=5
|
|
19
|
+
Requires-Dist: xmltodict>=1.0.3
|
|
20
|
+
Requires-Dist: pandas>=2.1.1
|
|
21
|
+
Requires-Dist: numpy>=1.26
|
|
22
|
+
Requires-Dist: scipy>=1.7
|
|
23
|
+
Requires-Dist: pydicom>=2
|
|
24
|
+
Requires-Dist: matplotlib>=3.9
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest>=6; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-mock>=3.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-dependency>=0.5; extra == "dev"
|
|
29
|
+
Requires-Dist: codespell; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff; extra == "dev"
|
|
31
|
+
Requires-Dist: bump2version>=1; extra == "dev"
|
|
32
|
+
Requires-Dist: build; extra == "dev"
|
|
33
|
+
Requires-Dist: twine; extra == "dev"
|
|
34
|
+
Requires-Dist: sphinx; extra == "dev"
|
|
35
|
+
Requires-Dist: sphinx-rtd-theme; extra == "dev"
|
|
36
|
+
Requires-Dist: sphinx-bootstrap-theme; extra == "dev"
|
|
37
|
+
Requires-Dist: furo; extra == "dev"
|
|
38
|
+
Requires-Dist: myst-parser; extra == "dev"
|
|
39
|
+
Requires-Dist: nbsphinx; extra == "dev"
|
|
40
|
+
Requires-Dist: nbsphinx-link; extra == "dev"
|
|
41
|
+
Requires-Dist: sphinx-argparse; extra == "dev"
|
|
42
|
+
Requires-Dist: numpydoc; extra == "dev"
|
|
43
|
+
Requires-Dist: docutils<0.21; extra == "dev"
|
|
44
|
+
Requires-Dist: notebook; extra == "dev"
|
|
45
|
+
Requires-Dist: jupyter; extra == "dev"
|
|
46
|
+
Provides-Extra: tensorflow
|
|
47
|
+
Requires-Dist: tensorflow>=2.16; extra == "tensorflow"
|
|
48
|
+
Provides-Extra: wfdb
|
|
49
|
+
Requires-Dist: wfdb<5,>=4.3.1; extra == "wfdb"
|
|
50
|
+
Provides-Extra: all
|
|
51
|
+
Requires-Dist: tensorflow>=2.16; extra == "all"
|
|
52
|
+
Requires-Dist: wfdb<5,>=4.3.1; extra == "all"
|
|
53
|
+
Dynamic: license-file
|
|
54
|
+
|
|
55
|
+
<!-- TODO once dev is merged into master and the pages job redeploys, switch
|
|
56
|
+
this back to the Sphinx-published URL:
|
|
57
|
+
https://SchmidtAF.gitlab.io/ECGProcess/_static/ecgp_logo.png -->
|
|
58
|
+
<img src="https://gitlab.com/SchmidtAF/ECGProcess/-/raw/d853ccf/docs/source/_static/ecgp_logo.png" alt="ECGProcess icon" width="250"/>
|
|
59
|
+
|
|
60
|
+
# An ECG processing module
|
|
61
|
+
__version__: `1.2.0`
|
|
62
|
+
|
|
63
|
+
Supports Python 3.11-3.13; the test suite runs against all three versions
|
|
64
|
+
in CI.
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
This repository hosts a collection of functions for processing
|
|
68
|
+
electrocardiogram (ECG) data and preparing it for analysis.
|
|
69
|
+
|
|
70
|
+
At a glance, ECGProcess is driven by three units:
|
|
71
|
+
|
|
72
|
+
* A **processor** unit, reads individual ECG files and based on
|
|
73
|
+
a user-supplied configuration file extracts waveform
|
|
74
|
+
signals, median beats, and metadata to python dictionaries; see [Configuration files](https://SchmidtAF.gitlab.io/ECGProcess/configuration_files.html)).
|
|
75
|
+
* The **table** unit, `ECGTable`, loops over a directory of ECG files,
|
|
76
|
+
calls the reader for each one, while applying optional engineering steps
|
|
77
|
+
(e.g. resampling, calibration, lead correction), and again optionally
|
|
78
|
+
concatenating multiple files together.
|
|
79
|
+
* A **writer** unit, tells `ECGTable` what to write to disk
|
|
80
|
+
(tables, NumPy arrays, WFDB records, images, ...).
|
|
81
|
+
|
|
82
|
+
Together these units implement an application programming interface (API),
|
|
83
|
+
mapping ECG data from distinct file types to class attributes
|
|
84
|
+
providing a fixed interface for downstream processing.
|
|
85
|
+
The package ships with boilerplate classes and validation utilities,
|
|
86
|
+
letting the user expand **processing** of additional file types,
|
|
87
|
+
build custom **engineering** (e.g. standardisation) pipelines, as well as
|
|
88
|
+
create custom **writers**.
|
|
89
|
+
|
|
90
|
+
Please consult the [documentation](https://SchmidtAF.gitlab.io/ECGProcess/)
|
|
91
|
+
for the full picture.
|
|
92
|
+
|
|
93
|
+
## Installation
|
|
94
|
+
The package is available on PyPI, and conda, with the latest source code
|
|
95
|
+
available on gitlab.
|
|
96
|
+
|
|
97
|
+
### Installation using PyPI
|
|
98
|
+
|
|
99
|
+
To install the package from PyPI, run:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pip install ecgprocess
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
This installs the latest stable release along with its dependencies.
|
|
106
|
+
|
|
107
|
+
### Installation using conda
|
|
108
|
+
|
|
109
|
+
A Conda package is maintained in my personal Conda channel.
|
|
110
|
+
To install from this channel, run:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
conda install afschmidt::ecgprocess
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Installation using gitlab
|
|
117
|
+
|
|
118
|
+
If you require the latest updates, potentially not yet formally released,
|
|
119
|
+
you can install the package directly from GitLab.
|
|
120
|
+
|
|
121
|
+
First, clone the repository and move into its root directory:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
git clone git@gitlab.com:SchmidtAF/ecgprocess.git
|
|
125
|
+
cd ecgprocess
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Install the dependencies:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# From the root of the repository
|
|
132
|
+
conda env create --file ./resources/conda/envs/conda_create.yaml
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
To add to an existing environment use:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# From the root of the repository
|
|
139
|
+
conda env update --file ./resources/conda/envs/conda_update.yaml
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Next the package can be installed:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
make install
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### Development
|
|
149
|
+
For development work, install the package in editable mode, with its
|
|
150
|
+
development dependencies (`pytest`, `codespell`, `sphinx`, ...) and Git
|
|
151
|
+
commit hooks configured:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
make install-dev
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
This command installs the package in editable mode with the `[dev]`
|
|
158
|
+
extras and configures Git commit hooks, allowing you to run `git pull`
|
|
159
|
+
to update the repository or switch branches without reinstalling.
|
|
160
|
+
|
|
161
|
+
Alternatively, you can install manually. This is exactly equivalent
|
|
162
|
+
to `make install-dev`:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
python -m pip install -e ".[dev]"
|
|
166
|
+
python .githooks/.setup_git_hooks.py
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Git Hooks Configuration
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
When setting up a development environment, the `setup-hooks` command
|
|
173
|
+
configures Git hooks to enforce conventional commit message formatting and
|
|
174
|
+
spell check using `codespell`.
|
|
175
|
+
|
|
176
|
+
To view the commit message format requirements, run:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
./.githooks/commit-msg -help
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
For frequent use, add this function to your shell configuration (`~/.bashrc`
|
|
183
|
+
or `~/.zshrc`):
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
commit-format-help() {
|
|
187
|
+
local git_root
|
|
188
|
+
git_root=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
189
|
+
|
|
190
|
+
if [ -z "$git_root" ]; then
|
|
191
|
+
echo "Error: Not inside a git repository"
|
|
192
|
+
return 1
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
local hook_path="$git_root/.githooks/commit-msg"
|
|
196
|
+
|
|
197
|
+
if [ ! -f "$hook_path" ]; then
|
|
198
|
+
echo "Error: commit-msg hook not found"
|
|
199
|
+
return 1
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
"$hook_path" --help
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Next steps...
|
|
207
|
+
If you installed with `make install-dev`, you might wish to run `pytest` to
|
|
208
|
+
confirm everything is in working order.
|
|
209
|
+
|
|
210
|
+
```sh
|
|
211
|
+
# From the root of the repository
|
|
212
|
+
pytest tests
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Usage
|
|
216
|
+
|
|
217
|
+
Please have a look at the [example](https://SchmidtAF.gitlab.io/ECGProcess/examples.html)
|
|
218
|
+
recipes.
|
|
219
|
+
|
|
220
|
+
## Icon
|
|
221
|
+
|
|
222
|
+
The package icon features the Etruscan shrew, one of the smallest
|
|
223
|
+
mammals, whose heart can beat over 1,500 times a minute, the fastest
|
|
224
|
+
heart rate of any mammal.
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
<!-- TODO once dev is merged into master and the pages job redeploys, switch
|
|
2
|
+
this back to the Sphinx-published URL:
|
|
3
|
+
https://SchmidtAF.gitlab.io/ECGProcess/_static/ecgp_logo.png -->
|
|
4
|
+
<img src="https://gitlab.com/SchmidtAF/ECGProcess/-/raw/d853ccf/docs/source/_static/ecgp_logo.png" alt="ECGProcess icon" width="250"/>
|
|
5
|
+
|
|
6
|
+
# An ECG processing module
|
|
7
|
+
__version__: `1.2.0`
|
|
8
|
+
|
|
9
|
+
Supports Python 3.11-3.13; the test suite runs against all three versions
|
|
10
|
+
in CI.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
This repository hosts a collection of functions for processing
|
|
14
|
+
electrocardiogram (ECG) data and preparing it for analysis.
|
|
15
|
+
|
|
16
|
+
At a glance, ECGProcess is driven by three units:
|
|
17
|
+
|
|
18
|
+
* A **processor** unit, reads individual ECG files and based on
|
|
19
|
+
a user-supplied configuration file extracts waveform
|
|
20
|
+
signals, median beats, and metadata to python dictionaries; see [Configuration files](https://SchmidtAF.gitlab.io/ECGProcess/configuration_files.html)).
|
|
21
|
+
* The **table** unit, `ECGTable`, loops over a directory of ECG files,
|
|
22
|
+
calls the reader for each one, while applying optional engineering steps
|
|
23
|
+
(e.g. resampling, calibration, lead correction), and again optionally
|
|
24
|
+
concatenating multiple files together.
|
|
25
|
+
* A **writer** unit, tells `ECGTable` what to write to disk
|
|
26
|
+
(tables, NumPy arrays, WFDB records, images, ...).
|
|
27
|
+
|
|
28
|
+
Together these units implement an application programming interface (API),
|
|
29
|
+
mapping ECG data from distinct file types to class attributes
|
|
30
|
+
providing a fixed interface for downstream processing.
|
|
31
|
+
The package ships with boilerplate classes and validation utilities,
|
|
32
|
+
letting the user expand **processing** of additional file types,
|
|
33
|
+
build custom **engineering** (e.g. standardisation) pipelines, as well as
|
|
34
|
+
create custom **writers**.
|
|
35
|
+
|
|
36
|
+
Please consult the [documentation](https://SchmidtAF.gitlab.io/ECGProcess/)
|
|
37
|
+
for the full picture.
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
The package is available on PyPI, and conda, with the latest source code
|
|
41
|
+
available on gitlab.
|
|
42
|
+
|
|
43
|
+
### Installation using PyPI
|
|
44
|
+
|
|
45
|
+
To install the package from PyPI, run:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install ecgprocess
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This installs the latest stable release along with its dependencies.
|
|
52
|
+
|
|
53
|
+
### Installation using conda
|
|
54
|
+
|
|
55
|
+
A Conda package is maintained in my personal Conda channel.
|
|
56
|
+
To install from this channel, run:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
conda install afschmidt::ecgprocess
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Installation using gitlab
|
|
63
|
+
|
|
64
|
+
If you require the latest updates, potentially not yet formally released,
|
|
65
|
+
you can install the package directly from GitLab.
|
|
66
|
+
|
|
67
|
+
First, clone the repository and move into its root directory:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
git clone git@gitlab.com:SchmidtAF/ecgprocess.git
|
|
71
|
+
cd ecgprocess
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Install the dependencies:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# From the root of the repository
|
|
78
|
+
conda env create --file ./resources/conda/envs/conda_create.yaml
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
To add to an existing environment use:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# From the root of the repository
|
|
85
|
+
conda env update --file ./resources/conda/envs/conda_update.yaml
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Next the package can be installed:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
make install
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### Development
|
|
95
|
+
For development work, install the package in editable mode, with its
|
|
96
|
+
development dependencies (`pytest`, `codespell`, `sphinx`, ...) and Git
|
|
97
|
+
commit hooks configured:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
make install-dev
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
This command installs the package in editable mode with the `[dev]`
|
|
104
|
+
extras and configures Git commit hooks, allowing you to run `git pull`
|
|
105
|
+
to update the repository or switch branches without reinstalling.
|
|
106
|
+
|
|
107
|
+
Alternatively, you can install manually. This is exactly equivalent
|
|
108
|
+
to `make install-dev`:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
python -m pip install -e ".[dev]"
|
|
112
|
+
python .githooks/.setup_git_hooks.py
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### Git Hooks Configuration
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
When setting up a development environment, the `setup-hooks` command
|
|
119
|
+
configures Git hooks to enforce conventional commit message formatting and
|
|
120
|
+
spell check using `codespell`.
|
|
121
|
+
|
|
122
|
+
To view the commit message format requirements, run:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
./.githooks/commit-msg -help
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
For frequent use, add this function to your shell configuration (`~/.bashrc`
|
|
129
|
+
or `~/.zshrc`):
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
commit-format-help() {
|
|
133
|
+
local git_root
|
|
134
|
+
git_root=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
135
|
+
|
|
136
|
+
if [ -z "$git_root" ]; then
|
|
137
|
+
echo "Error: Not inside a git repository"
|
|
138
|
+
return 1
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
local hook_path="$git_root/.githooks/commit-msg"
|
|
142
|
+
|
|
143
|
+
if [ ! -f "$hook_path" ]; then
|
|
144
|
+
echo "Error: commit-msg hook not found"
|
|
145
|
+
return 1
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
"$hook_path" --help
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Next steps...
|
|
153
|
+
If you installed with `make install-dev`, you might wish to run `pytest` to
|
|
154
|
+
confirm everything is in working order.
|
|
155
|
+
|
|
156
|
+
```sh
|
|
157
|
+
# From the root of the repository
|
|
158
|
+
pytest tests
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Usage
|
|
162
|
+
|
|
163
|
+
Please have a look at the [example](https://SchmidtAF.gitlab.io/ECGProcess/examples.html)
|
|
164
|
+
recipes.
|
|
165
|
+
|
|
166
|
+
## Icon
|
|
167
|
+
|
|
168
|
+
The package icon features the Etruscan shrew, one of the smallest
|
|
169
|
+
mammals, whose heart can beat over 1,500 times a minute, the fastest
|
|
170
|
+
heart rate of any mammal.
|