cardiolab 0.1.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 (159) hide show
  1. cardiolab-0.1.0/.claude/settings.local.json +9 -0
  2. cardiolab-0.1.0/.gitignore +6 -0
  3. cardiolab-0.1.0/.gitlab/issue_templates/bug_template.md +82 -0
  4. cardiolab-0.1.0/.gitlab/issue_templates/default_template.md +85 -0
  5. cardiolab-0.1.0/.gitlab-ci.yml +4 -0
  6. cardiolab-0.1.0/CHANGELOG.md +114 -0
  7. cardiolab-0.1.0/PKG-INFO +868 -0
  8. cardiolab-0.1.0/README.md +849 -0
  9. cardiolab-0.1.0/cardiolab/__init__.py +48 -0
  10. cardiolab-0.1.0/cardiolab/analytics/__init__.py +21 -0
  11. cardiolab-0.1.0/cardiolab/analytics/anomaly.py +176 -0
  12. cardiolab-0.1.0/cardiolab/analytics/baseline.py +271 -0
  13. cardiolab-0.1.0/cardiolab/analytics/scoring.py +314 -0
  14. cardiolab-0.1.0/cardiolab/analytics/trends.py +68 -0
  15. cardiolab-0.1.0/cardiolab/database/__init__.py +8 -0
  16. cardiolab-0.1.0/cardiolab/database/repository.py +1522 -0
  17. cardiolab-0.1.0/cardiolab/datasets/exports/ortho_2026-05-17_09-29-27.csv +2 -0
  18. cardiolab-0.1.0/cardiolab/datasets/exports/ortho_2026-05-17_09-29-27.json +101 -0
  19. cardiolab-0.1.0/cardiolab/datasets/exports/resting_history.csv +3 -0
  20. cardiolab-0.1.0/cardiolab/datasets/exports/resting_history.json +52 -0
  21. cardiolab-0.1.0/cardiolab/datasets/orthostatic/2026-05-17 09-29-27.json +703 -0
  22. cardiolab-0.1.0/cardiolab/datasets/resting/2026-04-24 07-52-36.json +329 -0
  23. cardiolab-0.1.0/cardiolab/datasets/resting/2026-04-25 07-58-25.json +600 -0
  24. cardiolab-0.1.0/cardiolab/docs/features/frequency_domain.md +269 -0
  25. cardiolab-0.1.0/cardiolab/docs/features/index.md +69 -0
  26. cardiolab-0.1.0/cardiolab/docs/features/nonlinear.md +397 -0
  27. cardiolab-0.1.0/cardiolab/docs/features/time_domain.md +202 -0
  28. cardiolab-0.1.0/cardiolab/docs/hrv_interpretations.md +112 -0
  29. cardiolab-0.1.0/cardiolab/docs/measurement.md +103 -0
  30. cardiolab-0.1.0/cardiolab/docs/protocols/cardiac_coherence.md +129 -0
  31. cardiolab-0.1.0/cardiolab/docs/protocols/cardiac_drift.md +157 -0
  32. cardiolab-0.1.0/cardiolab/docs/protocols/hrr.md +141 -0
  33. cardiolab-0.1.0/cardiolab/docs/protocols/orthostatic.md +257 -0
  34. cardiolab-0.1.0/cardiolab/docs/protocols/resting.md +120 -0
  35. cardiolab-0.1.0/cardiolab/docs/protocols/vo2max.md +167 -0
  36. cardiolab-0.1.0/cardiolab/docs/reporting/tables.md +534 -0
  37. cardiolab-0.1.0/cardiolab/docs/visualization/reading_charts.md +1259 -0
  38. cardiolab-0.1.0/cardiolab/docs/visualization/reading_spectral_charts.md +214 -0
  39. cardiolab-0.1.0/cardiolab/features/__init__.py +22 -0
  40. cardiolab-0.1.0/cardiolab/features/frequency_domain.py +228 -0
  41. cardiolab-0.1.0/cardiolab/features/nonlinear.py +358 -0
  42. cardiolab-0.1.0/cardiolab/features/time_domain.py +124 -0
  43. cardiolab-0.1.0/cardiolab/io/__init__.py +31 -0
  44. cardiolab-0.1.0/cardiolab/io/export.py +400 -0
  45. cardiolab-0.1.0/cardiolab/protocols/__init__.py +40 -0
  46. cardiolab-0.1.0/cardiolab/protocols/cardiac_coherence.py +197 -0
  47. cardiolab-0.1.0/cardiolab/protocols/cardiac_drift.py +200 -0
  48. cardiolab-0.1.0/cardiolab/protocols/hrr.py +199 -0
  49. cardiolab-0.1.0/cardiolab/protocols/orthostatic.py +670 -0
  50. cardiolab-0.1.0/cardiolab/protocols/resting.py +303 -0
  51. cardiolab-0.1.0/cardiolab/protocols/vo2max.py +195 -0
  52. cardiolab-0.1.0/cardiolab/reporting/__init__.py +46 -0
  53. cardiolab-0.1.0/cardiolab/reporting/_core.py +138 -0
  54. cardiolab-0.1.0/cardiolab/reporting/coherence.py +131 -0
  55. cardiolab-0.1.0/cardiolab/reporting/drift.py +111 -0
  56. cardiolab-0.1.0/cardiolab/reporting/hrr.py +114 -0
  57. cardiolab-0.1.0/cardiolab/reporting/orthostatic.py +200 -0
  58. cardiolab-0.1.0/cardiolab/reporting/resting.py +177 -0
  59. cardiolab-0.1.0/cardiolab/reporting/vo2max.py +180 -0
  60. cardiolab-0.1.0/cardiolab/scripts/__init__.py +1 -0
  61. cardiolab-0.1.0/cardiolab/scripts/import_rr.py +164 -0
  62. cardiolab-0.1.0/cardiolab/sensors_tools/__init__.py +7 -0
  63. cardiolab-0.1.0/cardiolab/sensors_tools/polar.py +177 -0
  64. cardiolab-0.1.0/cardiolab/signals/__init__.py +10 -0
  65. cardiolab-0.1.0/cardiolab/signals/ecg.py +248 -0
  66. cardiolab-0.1.0/cardiolab/signals/rr.py +350 -0
  67. cardiolab-0.1.0/cardiolab/visualization/__init__.py +134 -0
  68. cardiolab-0.1.0/cardiolab/visualization/coherence_plots.py +464 -0
  69. cardiolab-0.1.0/cardiolab/visualization/dashboard_plots.py +1318 -0
  70. cardiolab-0.1.0/cardiolab/visualization/drift_plots.py +364 -0
  71. cardiolab-0.1.0/cardiolab/visualization/hrr_plots.py +520 -0
  72. cardiolab-0.1.0/cardiolab/visualization/nonlinear_plots.py +664 -0
  73. cardiolab-0.1.0/cardiolab/visualization/plot.py +11 -0
  74. cardiolab-0.1.0/cardiolab/visualization/resting_plots.py +288 -0
  75. cardiolab-0.1.0/cardiolab/visualization/rr_plots.py +658 -0
  76. cardiolab-0.1.0/cardiolab/visualization/spectral_plots.py +695 -0
  77. cardiolab-0.1.0/cardiolab/visualization/vo2max_plots.py +499 -0
  78. cardiolab-0.1.0/example/.env.example +14 -0
  79. cardiolab-0.1.0/example/01_setup_database.py +65 -0
  80. cardiolab-0.1.0/example/02_feed_database.py +171 -0
  81. cardiolab-0.1.0/example/03_load_and_analyze.py +176 -0
  82. cardiolab-0.1.0/example/04_import_resting.py +44 -0
  83. cardiolab-0.1.0/example/05_import_orthostatic.py +72 -0
  84. cardiolab-0.1.0/example/06_rr_validation.py +59 -0
  85. cardiolab-0.1.0/example/07_auto_clean.py +68 -0
  86. cardiolab-0.1.0/example/08_to_dict_export.py +92 -0
  87. cardiolab-0.1.0/example/09_rr_signal_plots.py +177 -0
  88. cardiolab-0.1.0/example/10_resting_evolution_plots.py +247 -0
  89. cardiolab-0.1.0/example/11_spectral_plots.py +191 -0
  90. cardiolab-0.1.0/example/README.md +226 -0
  91. cardiolab-0.1.0/example/figures/10_01_rmssd_evolution.png +0 -0
  92. cardiolab-0.1.0/example/figures/10_02_readiness_score.png +0 -0
  93. cardiolab-0.1.0/example/figures/10_03_evolution_combined.png +0 -0
  94. cardiolab-0.1.0/example/figures/10_04_evolution_rolling.png +0 -0
  95. cardiolab-0.1.0/local/README.md +130 -0
  96. cardiolab-0.1.0/local/datasets/Juju/orthostatic/2026-05-21 07-18-50.txt +674 -0
  97. cardiolab-0.1.0/local/datasets/Juju/orthostatic/2026-05-27 08-07-14.txt +712 -0
  98. cardiolab-0.1.0/local/logs/import_log.csv +49 -0
  99. cardiolab-0.1.0/local/main_export.py +446 -0
  100. cardiolab-0.1.0/local/main_init_db.py +190 -0
  101. cardiolab-0.1.0/local/main_report.py +323 -0
  102. cardiolab-0.1.0/local/main_save_to_db.py +574 -0
  103. cardiolab-0.1.0/local/main_visualize.py +561 -0
  104. cardiolab-0.1.0/local/processed/Juju/resting/2026-04-24 07-52-36.txt +320 -0
  105. cardiolab-0.1.0/local/processed/Juju/resting/2026-04-25 07-58-25.txt +591 -0
  106. cardiolab-0.1.0/local/processed/Juju/resting/2026-04-26 07-40-41.txt +307 -0
  107. cardiolab-0.1.0/local/processed/Juju/resting/2026-04-27 07-01-19.txt +296 -0
  108. cardiolab-0.1.0/local/processed/Juju/resting/2026-04-28 07-01-05.txt +299 -0
  109. cardiolab-0.1.0/local/processed/Juju/resting/2026-04-30 07-01-38.txt +283 -0
  110. cardiolab-0.1.0/local/processed/Juju/resting/2026-05-18 07-18-42.txt +271 -0
  111. cardiolab-0.1.0/local/processed/Juju/resting/2026-05-19 07-03-13.txt +334 -0
  112. cardiolab-0.1.0/local/reports/Juju_resting_20260527_160607.html +352 -0
  113. cardiolab-0.1.0/output/coherence_mini.png +0 -0
  114. cardiolab-0.1.0/output/drift_mini.png +0 -0
  115. cardiolab-0.1.0/output/heatmap.png +0 -0
  116. cardiolab-0.1.0/output/hrr_mini.png +0 -0
  117. cardiolab-0.1.0/output/readiness.png +0 -0
  118. cardiolab-0.1.0/output/resting_mini.png +0 -0
  119. cardiolab-0.1.0/output/session_dashboard.png +0 -0
  120. cardiolab-0.1.0/output/vo2max_mini.png +0 -0
  121. cardiolab-0.1.0/pipeline-notebook.ipynb +3781 -0
  122. cardiolab-0.1.0/pyproject.toml +98 -0
  123. cardiolab-0.1.0/pystest.ini +45 -0
  124. cardiolab-0.1.0/requirements.txt +17 -0
  125. cardiolab-0.1.0/tests/analytics/test_anomaly.py +448 -0
  126. cardiolab-0.1.0/tests/analytics/test_baseline.py +402 -0
  127. cardiolab-0.1.0/tests/analytics/test_scoring.py +652 -0
  128. cardiolab-0.1.0/tests/analytics/test_trends.py +383 -0
  129. cardiolab-0.1.0/tests/conftest.py +420 -0
  130. cardiolab-0.1.0/tests/database/test_repository.py +1060 -0
  131. cardiolab-0.1.0/tests/export/test_export.py +513 -0
  132. cardiolab-0.1.0/tests/features/test_frequency_domain.py +349 -0
  133. cardiolab-0.1.0/tests/features/test_nonlinear.py +322 -0
  134. cardiolab-0.1.0/tests/features/test_time_domain.py +70 -0
  135. cardiolab-0.1.0/tests/protocols/test_cardiac_coherence.py +186 -0
  136. cardiolab-0.1.0/tests/protocols/test_cardiac_drift.py +209 -0
  137. cardiolab-0.1.0/tests/protocols/test_hrr.py +225 -0
  138. cardiolab-0.1.0/tests/protocols/test_orthostatic.py +686 -0
  139. cardiolab-0.1.0/tests/protocols/test_resting.py +482 -0
  140. cardiolab-0.1.0/tests/protocols/test_vo2max.py +224 -0
  141. cardiolab-0.1.0/tests/reporting/__init__.py +1 -0
  142. cardiolab-0.1.0/tests/reporting/test_coherence.py +199 -0
  143. cardiolab-0.1.0/tests/reporting/test_drift.py +170 -0
  144. cardiolab-0.1.0/tests/reporting/test_hrr.py +177 -0
  145. cardiolab-0.1.0/tests/reporting/test_orthostatic.py +333 -0
  146. cardiolab-0.1.0/tests/reporting/test_resting.py +243 -0
  147. cardiolab-0.1.0/tests/reporting/test_vo2max.py +256 -0
  148. cardiolab-0.1.0/tests/sensors_tools/test_polar.py +397 -0
  149. cardiolab-0.1.0/tests/signals/test_ecg.py +105 -0
  150. cardiolab-0.1.0/tests/signals/test_rr.py +254 -0
  151. cardiolab-0.1.0/tests/visualization/test_coherence_plots.py +320 -0
  152. cardiolab-0.1.0/tests/visualization/test_dashboard_plots.py +641 -0
  153. cardiolab-0.1.0/tests/visualization/test_drift_plots.py +314 -0
  154. cardiolab-0.1.0/tests/visualization/test_hrr_plots.py +383 -0
  155. cardiolab-0.1.0/tests/visualization/test_nonlinear_plots.py +432 -0
  156. cardiolab-0.1.0/tests/visualization/test_resting_plots.py +349 -0
  157. cardiolab-0.1.0/tests/visualization/test_rr_plots.py +285 -0
  158. cardiolab-0.1.0/tests/visualization/test_spectral_plots.py +357 -0
  159. cardiolab-0.1.0/tests/visualization/test_vo2max_plots.py +453 -0
@@ -0,0 +1,9 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(ruff check *)",
5
+ "Bash(python -m pytest tests/visualization/test_nonlinear_plots.py -v --tb=short -q)",
6
+ "Bash(python -m pytest tests/visualization/ -q)"
7
+ ]
8
+ }
9
+ }
@@ -0,0 +1,6 @@
1
+ .venv
2
+ main_test.py
3
+ .pytest_cache
4
+ __pycache__
5
+ cardiolab/datasets/raw/
6
+ .env
@@ -0,0 +1,82 @@
1
+ ## πŸ“Œ Description
2
+
3
+ **Describe the bug clearly.**
4
+
5
+ <!-- What behaviour is incorrect? -->
6
+
7
+ ---
8
+
9
+ ## πŸ” Steps to reproduce
10
+
11
+ **Describe precisely how to reproduce the bug.**
12
+
13
+ 1.
14
+ 2.
15
+ 3.
16
+
17
+ ---
18
+
19
+ ## ❗ Expected behaviour
20
+
21
+ **Explain what should happen.**
22
+
23
+ ---
24
+
25
+ ## ❌ Actual behaviour
26
+
27
+ **Describe what actually happens.**
28
+
29
+ ---
30
+
31
+ ## πŸ–₯️ Technical context
32
+
33
+ **Provide the technical information needed to understand the bug.**
34
+
35
+ * Code version:
36
+ * Affected module:
37
+ * Input data used:
38
+ * Environment:
39
+
40
+ ---
41
+
42
+ ## πŸ“Ž Logs / Data / Screenshots
43
+
44
+ **Attach any artefacts that help diagnose the bug.**
45
+
46
+ ---
47
+
48
+ ## Root cause hypothesis (optional)
49
+
50
+ **Suggest a possible explanation for the bug.**
51
+
52
+ ---
53
+
54
+ ## Proposed fix (optional)
55
+
56
+ **Suggest a solution if one has been identified.**
57
+
58
+ ---
59
+
60
+ ## βœ… Acceptance criteria
61
+
62
+ **Define the conditions under which the bug can be considered fixed.**
63
+
64
+ * [ ] Bug is no longer reproducible
65
+ * [ ] No regression introduced
66
+ * [ ] Tests added or updated
67
+
68
+ ---
69
+
70
+ ## πŸ§ͺ Testing
71
+
72
+ **Explain how to verify that the fix works.**
73
+
74
+ *
75
+
76
+ ---
77
+
78
+ ## 🧩 Related issues
79
+
80
+ **List any related issues or dependencies.**
81
+
82
+ *
@@ -0,0 +1,85 @@
1
+ ## 🎯 Goal
2
+
3
+ **Describe clearly what this issue should accomplish.**
4
+
5
+ <!-- What problem does this issue solve? -->
6
+
7
+ ---
8
+
9
+ ## 🧠 Context
10
+
11
+ **Explain why this issue matters in the project.**
12
+
13
+ <!-- Link to pipeline, architecture, or scientific logic if relevant -->
14
+
15
+ ---
16
+
17
+ ## πŸ“¦ Scope
18
+
19
+ **List precisely what is included in this issue.**
20
+
21
+ <!-- Define deliverables to avoid ambiguity -->
22
+
23
+ *
24
+
25
+ ---
26
+
27
+ ## ❌ Out of scope
28
+
29
+ **List explicitly what is NOT part of this issue.**
30
+
31
+ <!-- Prevents scope creep and helps break work into smaller pieces -->
32
+
33
+ *
34
+
35
+ ---
36
+
37
+ ## πŸ› οΈ Proposed implementation
38
+
39
+ **Describe the planned technical approach.**
40
+
41
+ <!-- Classes, functions, modules, or overall strategy -->
42
+
43
+ *
44
+
45
+ ---
46
+
47
+ ## πŸ“Š Acceptance criteria
48
+
49
+ **Define the conditions that must be met for this issue to be closed.**
50
+
51
+ <!-- Must be verifiable and measurable -->
52
+
53
+ * [ ]
54
+ * [ ]
55
+ * [ ]
56
+
57
+ ---
58
+
59
+ ## πŸ§ͺ Testing
60
+
61
+ **Explain how to verify that the implementation is correct.**
62
+
63
+ <!-- Unit tests, happy path, edge cases -->
64
+
65
+ *
66
+
67
+ ---
68
+
69
+ ## πŸ“š References
70
+
71
+ **Add relevant sources (scientific or technical).**
72
+
73
+ <!-- Papers, standards, documentation -->
74
+
75
+ *
76
+
77
+ ---
78
+
79
+ ## 🧩 Related issues
80
+
81
+ **List related issues or dependencies.**
82
+
83
+ <!-- Dependencies or logical continuity -->
84
+
85
+ *
@@ -0,0 +1,4 @@
1
+ include:
2
+ - project: 'project-jmilon-devsecops/ci-cd/pipeline-python-centralisee'
3
+ ref: 0.1.0
4
+ file: 'pipelines/python-package-pipeline.yml'
@@ -0,0 +1,114 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] β€” 2026-05-26
11
+
12
+ First public release. The package covers the full analysis pipeline from raw RR
13
+ intervals to clinical reporting, across six validated physiological protocols.
14
+
15
+ ### Added β€” Core signals
16
+
17
+ - `signals/rr.py` β€” `RRSeries`: typed representation of RR intervals with
18
+ input validation (range, length), heart-rate conversion, and filtering helpers.
19
+ - `signals/ecg.py` β€” `ECGSignal`: ECG signal loader with R-peak detection and
20
+ RR extraction via `scipy`.
21
+
22
+ ### Added β€” HRV feature extraction
23
+
24
+ - `features/time_domain.py` β€” RMSSD, SDNN, SD1, SD2, SD1/SD2 ratio, pNN50,
25
+ mean HR. Fully vectorised via NumPy.
26
+ - `features/frequency_domain.py` β€” Power spectral density (VLF, LF, HF, LF/HF
27
+ ratio) computed by FFT and Lomb-Scargle. Named physiological band constants.
28
+ - `features/nonlinear.py` β€” DFA Ξ±1 (log-log slope), approximate entropy (ApEn),
29
+ sample entropy (SampEn), PoincarΓ© SD1/SD2.
30
+
31
+ ### Added β€” Clinical protocols
32
+
33
+ - `protocols/resting.py` β€” Resting HRV analysis. Computes a multi-domain score
34
+ and fitness category from a `RRSeries` and user demographics.
35
+ - `protocols/orthostatic.py` β€” Active orthostatic test (supine β†’ standing).
36
+ Computes HR delta, vagal reactivity index, and clinical interpretation.
37
+ - `protocols/cardiac_coherence.py` β€” Cardiac coherence analysis. Resonance
38
+ frequency, peak power, coherence score (McCraty / HeartMath standard).
39
+ - `protocols/hrr.py` β€” Heart Rate Recovery. HRR60 and HRR120 with Cole et al.
40
+ 1999 clinical categories.
41
+ - `protocols/cardiac_drift.py` β€” Cardiac drift by linear regression over sliding
42
+ windows. Drift rate (bpm/min), magnitude, RΒ², and clinical interpretation.
43
+ - `protocols/vo2max.py` β€” VO2max estimation via three validated models: Uth
44
+ (requires HRmax), Esco-Flatt (HRV-derived), and ln-RMSSD (Nunan). ACSM 2022
45
+ fitness categories.
46
+
47
+ ### Added β€” Visualization
48
+
49
+ - `visualization/rr_plots.py` β€” Time-series plot of RR intervals with ectopic
50
+ beat markers.
51
+ - `visualization/spectral_plots.py` β€” Power spectral density plots (FFT /
52
+ Lomb-Scargle) with physiological band overlays (VLF, LF, HF).
53
+ - `visualization/nonlinear_plots.py` β€” PoincarΓ© scatter plot and DFA log-log
54
+ regression.
55
+ - `visualization/resting_plots.py` β€” Longitudinal evolution of resting HRV
56
+ indicators across sessions.
57
+ - `visualization/coherence_plots.py` β€” Coherence spectrogram and session score
58
+ timeline.
59
+ - `visualization/hrr_plots.py` β€” HR recovery curve with HRR60/HRR120 markers
60
+ and reference bands.
61
+ - `visualization/drift_plots.py` β€” Drift trajectory with linear regression
62
+ overlay and magnitude annotation.
63
+ - `visualization/vo2max_plots.py` β€” Side-by-side comparison of three VO2max
64
+ model estimates with ACSM category bands.
65
+ - `visualization/dashboard_plots.py` β€” Eight global dashboard functions and five
66
+ per-protocol mini-dashboards (resting, orthostatic, coherence, HRR, drift,
67
+ VO2max).
68
+
69
+ ### Added β€” Tabular reporting
70
+
71
+ Nine `pd.Styler`-based functions exportable to HTML, Excel, or Jupyter display:
72
+
73
+ - `reporting/resting.py` β€” `table_resting_history`, `table_resting_session`.
74
+ - `reporting/orthostatic.py` β€” `table_orthostatic_comparison` (supine vs.
75
+ standing with deltas), `table_orthostatic_history`.
76
+ - `reporting/hrr.py` β€” `table_hrr_history`.
77
+ - `reporting/drift.py` β€” `table_drift_history`.
78
+ - `reporting/coherence.py` β€” `table_coherence_history` (derived category column:
79
+ low / moderate / high).
80
+ - `reporting/vo2max.py` β€” `table_vo2max_history`, `table_vo2max_session`.
81
+ - Shared colour helpers in `reporting/_core.py`: green-to-red gradients for
82
+ every clinical indicator, category palette highlighting.
83
+
84
+ ### Added β€” Database persistence
85
+
86
+ - `database/schema.py` β€” PostgreSQL schema creation (sessions, HRV features,
87
+ protocol results).
88
+ - `database/repository.py` β€” Named-query repository pattern for all six
89
+ protocols; insert and fetch by user / date range.
90
+
91
+ ### Added β€” I/O and sensors
92
+
93
+ - `io/export.py` β€” Export protocol results to CSV and JSON.
94
+ - `sensors_tools/polar.py` β€” Parser for Polar RR export format (`.txt`).
95
+ - `scripts/import_rr.py` β€” CLI script to import RR data files into PostgreSQL.
96
+
97
+ ### Added β€” Analytics
98
+
99
+ - `analytics/baseline.py` β€” User baseline computation from longitudinal history
100
+ (rolling statistics).
101
+ - `analytics/anomaly.py` β€” Z-score anomaly detection on HRV indicators.
102
+ - `analytics/scoring.py` β€” Composite multi-domain HRV score.
103
+ - `analytics/trends.py` β€” Longitudinal trend analysis (slope, direction).
104
+
105
+ ### Added β€” Quality and tooling
106
+
107
+ - **1 111 unit tests** (pytest), 2 skipped (PostgreSQL integration β€” requires
108
+ live DB).
109
+ - **Zero ruff errors** β€” rules E, F, I, B, UP, SIM, D, N, S enforced.
110
+ - `pipeline-notebook.ipynb` β€” end-to-end Jupyter pipeline covering all six
111
+ protocols: acquisition β†’ features β†’ analysis β†’ visualisation β†’ reporting.
112
+ - Full API documentation under `docs/` (signal, protocol, visualization,
113
+ reporting layers).
114
+ - `pyproject.toml` configured for `hatchling` build, `ruff` lint, `pytest`.