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.
Files changed (59) hide show
  1. ecgprocess-1.2.0/ECGProcess.egg-info/PKG-INFO +224 -0
  2. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ECGProcess.egg-info/SOURCES.txt +14 -1
  3. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ECGProcess.egg-info/requires.txt +11 -2
  4. ecgprocess-1.2.0/PKG-INFO +224 -0
  5. ecgprocess-1.2.0/README.md +170 -0
  6. ecgprocess-1.2.0/ecgprocess/__init__.py +34 -0
  7. ecgprocess-1.2.0/ecgprocess/_version.py +1 -0
  8. ecgprocess-1.2.0/ecgprocess/constants.py +315 -0
  9. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/errors.py +191 -14
  10. ecgprocess-1.2.0/ecgprocess/example_data/example_datasets/example-XMLWriter1.json +31 -0
  11. ecgprocess-1.2.0/ecgprocess/example_data/example_datasets/example-XMLWriter1.xsd +27 -0
  12. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/examples.py +60 -10
  13. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/plot_ecgs.py +189 -21
  14. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/process_dicom.py +5 -21
  15. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/process_xml.py +93 -43
  16. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/tabular.py +404 -532
  17. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/utils/config_tools.py +56 -45
  18. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/utils/ecg_tools.py +33 -32
  19. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/utils/engineering_tools.py +28 -12
  20. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/utils/general.py +53 -23
  21. ecgprocess-1.2.0/ecgprocess/writer/__init__.py +69 -0
  22. ecgprocess-1.2.0/ecgprocess/writer/writer_base.py +670 -0
  23. ecgprocess-1.2.0/ecgprocess/writer/writer_figure.py +302 -0
  24. ecgprocess-1.2.0/ecgprocess/writer/writer_numpy.py +247 -0
  25. ecgprocess-1.2.0/ecgprocess/writer/writer_pixel.py +295 -0
  26. ecgprocess-1.2.0/ecgprocess/writer/writer_table.py +334 -0
  27. ecgprocess-1.2.0/ecgprocess/writer/writer_tfrecord.py +144 -0
  28. ecgprocess-1.2.0/ecgprocess/writer/writer_wfdb.py +291 -0
  29. ecgprocess-1.2.0/ecgprocess/writer/writer_xml.py +572 -0
  30. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/pyproject.toml +16 -2
  31. ecgprocess-1.2.0/requirements-tensorflow.txt +1 -0
  32. ecgprocess-1.2.0/requirements-wfdb.txt +1 -0
  33. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/requirements.txt +1 -2
  34. ecgprocess-1.1.0/ECGProcess.egg-info/PKG-INFO +0 -153
  35. ecgprocess-1.1.0/PKG-INFO +0 -153
  36. ecgprocess-1.1.0/README.md +0 -105
  37. ecgprocess-1.1.0/ecgprocess/__init__.py +0 -1
  38. ecgprocess-1.1.0/ecgprocess/_version.py +0 -1
  39. ecgprocess-1.1.0/ecgprocess/constants.py +0 -170
  40. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ECGProcess.egg-info/dependency_links.txt +0 -0
  41. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ECGProcess.egg-info/top_level.txt +0 -0
  42. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/LICENCE.txt +0 -0
  43. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/__init__.py +0 -0
  44. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/.example-XML1.xml.un~ +0 -0
  45. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/.example-XML1.xsd.un~ +0 -0
  46. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/.example-XML1_a.xsd.un~ +0 -0
  47. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/.example-XML1_d.xsd.un~ +0 -0
  48. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/.example-XML1_wrong.xsd.un~ +0 -0
  49. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/example-DICOM1.dcm +0 -0
  50. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/example-DICOM2.dcm +0 -0
  51. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/example-XML1.xml +0 -0
  52. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/example-XML1.xsd +0 -0
  53. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/example-XML1_error.xsd +0 -0
  54. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/example-XML1_wrong.xsd +0 -0
  55. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/example_data/example_datasets/string_data.txt +0 -0
  56. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/utils/__init__.py +0 -0
  57. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/ecgprocess/utils/reader_tools.py +0 -0
  58. {ecgprocess-1.1.0 → ecgprocess-1.2.0}/requirements-dev.txt +0 -0
  59. {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.14
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.