cgmpy 0.5.2__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 (236) hide show
  1. cgmpy-0.5.2/.editorconfig +56 -0
  2. cgmpy-0.5.2/.gitattributes +70 -0
  3. cgmpy-0.5.2/.github/ISSUE_TEMPLATE/bug_report.md +60 -0
  4. cgmpy-0.5.2/.github/ISSUE_TEMPLATE/feature_request.md +54 -0
  5. cgmpy-0.5.2/.github/ISSUE_TEMPLATE/question.md +28 -0
  6. cgmpy-0.5.2/.github/PULL_REQUEST_TEMPLATE.md +67 -0
  7. cgmpy-0.5.2/.github/dependabot.yml +42 -0
  8. cgmpy-0.5.2/.github/labeler.yml +39 -0
  9. cgmpy-0.5.2/.github/workflows/check-line-endings.yml +47 -0
  10. cgmpy-0.5.2/.github/workflows/ci.yml +149 -0
  11. cgmpy-0.5.2/.github/workflows/codeql.yml +43 -0
  12. cgmpy-0.5.2/.github/workflows/docs.yml +57 -0
  13. cgmpy-0.5.2/.github/workflows/pr-standards.yml +63 -0
  14. cgmpy-0.5.2/.github/workflows/publish.yml +61 -0
  15. cgmpy-0.5.2/.github/workflows/release-please.yml +45 -0
  16. cgmpy-0.5.2/.gitignore +127 -0
  17. cgmpy-0.5.2/.opencode/agents/agata-integrator.md +86 -0
  18. cgmpy-0.5.2/.opencode/agents/cgmpy-architect.md +82 -0
  19. cgmpy-0.5.2/.opencode/agents/data-guardian.md +65 -0
  20. cgmpy-0.5.2/.opencode/agents/docs-maintainer.md +84 -0
  21. cgmpy-0.5.2/.opencode/agents/metrics-guardian.md +72 -0
  22. cgmpy-0.5.2/.opencode/agents/plotting-guardian.md +62 -0
  23. cgmpy-0.5.2/.opencode/agents/release-manager.md +89 -0
  24. cgmpy-0.5.2/.opencode/agents/security-guard.md +82 -0
  25. cgmpy-0.5.2/.opencode/agents/test-engineer.md +79 -0
  26. cgmpy-0.5.2/.opencode/commands/end.md +55 -0
  27. cgmpy-0.5.2/.opencode/commands/release.md +63 -0
  28. cgmpy-0.5.2/.opencode/commands/start.md +40 -0
  29. cgmpy-0.5.2/.opencode/commands/test.md +43 -0
  30. cgmpy-0.5.2/.opencode/opencode.jsonc +5 -0
  31. cgmpy-0.5.2/.opencode/rules/development.md +68 -0
  32. cgmpy-0.5.2/.opencode/rules/documentation.md +118 -0
  33. cgmpy-0.5.2/.opencode/rules/library-structure.md +103 -0
  34. cgmpy-0.5.2/.opencode/rules/security.md +79 -0
  35. cgmpy-0.5.2/.opencode/rules/testing.md +106 -0
  36. cgmpy-0.5.2/.opencode/skills/docs-maintainer/SKILL.md +82 -0
  37. cgmpy-0.5.2/.opencode/skills/git-advisor/SKILL.md +97 -0
  38. cgmpy-0.5.2/.opencode/skills/post-coding-check/SKILL.md +97 -0
  39. cgmpy-0.5.2/.opencode/skills/python-lib/SKILL.md +122 -0
  40. cgmpy-0.5.2/.opencode/skills/security-guard/SKILL.md +77 -0
  41. cgmpy-0.5.2/AGENTS.md +316 -0
  42. cgmpy-0.5.2/CHANGELOG.md +270 -0
  43. cgmpy-0.5.2/CODE_OF_CONDUCT.md +126 -0
  44. cgmpy-0.5.2/CONTRIBUTING.md +251 -0
  45. cgmpy-0.5.2/LICENSE +21 -0
  46. cgmpy-0.5.2/MANIFEST.in +74 -0
  47. cgmpy-0.5.2/Makefile +220 -0
  48. cgmpy-0.5.2/PKG-INFO +218 -0
  49. cgmpy-0.5.2/README.md +162 -0
  50. cgmpy-0.5.2/ROADMAP.md +266 -0
  51. cgmpy-0.5.2/SECURITY.md +91 -0
  52. cgmpy-0.5.2/cgmpy/__init__.py +55 -0
  53. cgmpy-0.5.2/cgmpy/agata/__init__.py +21 -0
  54. cgmpy-0.5.2/cgmpy/agata/adapter.py +102 -0
  55. cgmpy-0.5.2/cgmpy/agata/metrics.py +193 -0
  56. cgmpy-0.5.2/cgmpy/analysis/__init__.py +15 -0
  57. cgmpy-0.5.2/cgmpy/analysis/core.py +1103 -0
  58. cgmpy-0.5.2/cgmpy/cli.py +144 -0
  59. cgmpy-0.5.2/cgmpy/data/__init__.py +50 -0
  60. cgmpy-0.5.2/cgmpy/data/_constants.py +5 -0
  61. cgmpy-0.5.2/cgmpy/data/analyzer.py +204 -0
  62. cgmpy-0.5.2/cgmpy/data/core.py +536 -0
  63. cgmpy-0.5.2/cgmpy/data/exporter.py +294 -0
  64. cgmpy-0.5.2/cgmpy/data/loader.py +158 -0
  65. cgmpy-0.5.2/cgmpy/data/pregnancy_data.py +198 -0
  66. cgmpy-0.5.2/cgmpy/data/processor.py +515 -0
  67. cgmpy-0.5.2/cgmpy/data/specialized.py +289 -0
  68. cgmpy-0.5.2/cgmpy/errors.py +243 -0
  69. cgmpy-0.5.2/cgmpy/metrics/__init__.py +18 -0
  70. cgmpy-0.5.2/cgmpy/metrics/basic.py +99 -0
  71. cgmpy-0.5.2/cgmpy/metrics/pregnancy.py +242 -0
  72. cgmpy-0.5.2/cgmpy/metrics/targets.py +91 -0
  73. cgmpy-0.5.2/cgmpy/metrics/time_in_range.py +104 -0
  74. cgmpy-0.5.2/cgmpy/metrics/units.py +36 -0
  75. cgmpy-0.5.2/cgmpy/metrics/validation.py +159 -0
  76. cgmpy-0.5.2/cgmpy/metrics/variability/__init__.py +29 -0
  77. cgmpy-0.5.2/cgmpy/metrics/variability/_base.py +49 -0
  78. cgmpy-0.5.2/cgmpy/metrics/variability/conga.py +83 -0
  79. cgmpy-0.5.2/cgmpy/metrics/variability/lability.py +148 -0
  80. cgmpy-0.5.2/cgmpy/metrics/variability/mage.py +726 -0
  81. cgmpy-0.5.2/cgmpy/metrics/variability/modd.py +70 -0
  82. cgmpy-0.5.2/cgmpy/metrics/variability/risk.py +351 -0
  83. cgmpy-0.5.2/cgmpy/metrics/variability/sd.py +773 -0
  84. cgmpy-0.5.2/cgmpy/plotting/__init__.py +14 -0
  85. cgmpy-0.5.2/cgmpy/plotting/_utils.py +33 -0
  86. cgmpy-0.5.2/cgmpy/plotting/agp.py +283 -0
  87. cgmpy-0.5.2/cgmpy/plotting/daily_plots.py +292 -0
  88. cgmpy-0.5.2/cgmpy/plotting/mage_excursions.py +231 -0
  89. cgmpy-0.5.2/cgmpy/plotting/statistical_plots.py +311 -0
  90. cgmpy-0.5.2/cgmpy/py.typed +1 -0
  91. cgmpy-0.5.2/cgmpy/utils/__init__.py +13 -0
  92. cgmpy-0.5.2/cgmpy/utils/date_utils.py +200 -0
  93. cgmpy-0.5.2/cgmpy.egg-info/PKG-INFO +218 -0
  94. cgmpy-0.5.2/cgmpy.egg-info/SOURCES.txt +234 -0
  95. cgmpy-0.5.2/cgmpy.egg-info/dependency_links.txt +1 -0
  96. cgmpy-0.5.2/cgmpy.egg-info/entry_points.txt +2 -0
  97. cgmpy-0.5.2/cgmpy.egg-info/requires.txt +29 -0
  98. cgmpy-0.5.2/cgmpy.egg-info/top_level.txt +1 -0
  99. cgmpy-0.5.2/commitlint.config.cjs +118 -0
  100. cgmpy-0.5.2/docs/api/agata.md +22 -0
  101. cgmpy-0.5.2/docs/api/data.md +101 -0
  102. cgmpy-0.5.2/docs/api/metrics.md +60 -0
  103. cgmpy-0.5.2/docs/api/plotting.md +52 -0
  104. cgmpy-0.5.2/docs/architecture/decisions/0001-record-architecture-decisions.md +63 -0
  105. cgmpy-0.5.2/docs/architecture/decisions/0002-pyproject-toml-config.md +75 -0
  106. cgmpy-0.5.2/docs/architecture/decisions/0003-facade-mixin-pattern.md +83 -0
  107. cgmpy-0.5.2/docs/architecture/decisions/0004-agent-harness-asymmetric.md +82 -0
  108. cgmpy-0.5.2/docs/architecture/decisions/index.md +73 -0
  109. cgmpy-0.5.2/docs/architecture/system-overview.md +127 -0
  110. cgmpy-0.5.2/docs/development/architecture.md +121 -0
  111. cgmpy-0.5.2/docs/development/concepts/caching-strategies.md +388 -0
  112. cgmpy-0.5.2/docs/development/concepts/dependency-injection.md +264 -0
  113. cgmpy-0.5.2/docs/development/concepts/deprecation-policy.md +124 -0
  114. cgmpy-0.5.2/docs/development/concepts/facade-pattern.md +117 -0
  115. cgmpy-0.5.2/docs/development/concepts/inheritance-vs-composition.md +359 -0
  116. cgmpy-0.5.2/docs/development/concepts/mro-diamond-problem.md +153 -0
  117. cgmpy-0.5.2/docs/development/concepts/pure-functions.md +178 -0
  118. cgmpy-0.5.2/docs/development/concepts/type-hints-for-science.md +311 -0
  119. cgmpy-0.5.2/docs/development/git-workflow.md +110 -0
  120. cgmpy-0.5.2/docs/development/release-process.md +123 -0
  121. cgmpy-0.5.2/docs/development/setup.md +147 -0
  122. cgmpy-0.5.2/docs/development/testing.md +157 -0
  123. cgmpy-0.5.2/docs/getting-started/data-formats.md +145 -0
  124. cgmpy-0.5.2/docs/getting-started/installation.md +113 -0
  125. cgmpy-0.5.2/docs/getting-started/quickstart.md +136 -0
  126. cgmpy-0.5.2/docs/index.md +58 -0
  127. cgmpy-0.5.2/docs/learning/learning-path.es.md +70 -0
  128. cgmpy-0.5.2/docs/learning/learning-path.md +64 -0
  129. cgmpy-0.5.2/docs/learning/what-is-ci-cd.es.md +101 -0
  130. cgmpy-0.5.2/docs/learning/what-is-ci-cd.md +101 -0
  131. cgmpy-0.5.2/docs/learning/what-is-conventional-commits.es.md +66 -0
  132. cgmpy-0.5.2/docs/learning/what-is-conventional-commits.md +66 -0
  133. cgmpy-0.5.2/docs/learning/what-is-makefile.es.md +55 -0
  134. cgmpy-0.5.2/docs/learning/what-is-makefile.md +55 -0
  135. cgmpy-0.5.2/docs/learning/what-is-mkdocs.es.md +45 -0
  136. cgmpy-0.5.2/docs/learning/what-is-mkdocs.md +45 -0
  137. cgmpy-0.5.2/docs/learning/what-is-mypy.es.md +97 -0
  138. cgmpy-0.5.2/docs/learning/what-is-mypy.md +97 -0
  139. cgmpy-0.5.2/docs/learning/what-is-pre-commit.es.md +88 -0
  140. cgmpy-0.5.2/docs/learning/what-is-pre-commit.md +87 -0
  141. cgmpy-0.5.2/docs/learning/what-is-pytest.es.md +123 -0
  142. cgmpy-0.5.2/docs/learning/what-is-pytest.md +123 -0
  143. cgmpy-0.5.2/docs/learning/what-is-release-please.es.md +41 -0
  144. cgmpy-0.5.2/docs/learning/what-is-release-please.md +41 -0
  145. cgmpy-0.5.2/docs/learning/what-is-ruff.es.md +127 -0
  146. cgmpy-0.5.2/docs/learning/what-is-ruff.md +122 -0
  147. cgmpy-0.5.2/docs/legal.md +159 -0
  148. cgmpy-0.5.2/docs/user-guide/agata-integration.md +107 -0
  149. cgmpy-0.5.2/docs/user-guide/cli.md +118 -0
  150. cgmpy-0.5.2/docs/user-guide/computing-metrics.md +144 -0
  151. cgmpy-0.5.2/docs/user-guide/loading-data.md +214 -0
  152. cgmpy-0.5.2/docs/user-guide/pregnancy-analysis.md +130 -0
  153. cgmpy-0.5.2/docs/user-guide/supported-devices.md +101 -0
  154. cgmpy-0.5.2/docs/user-guide/visualization.md +128 -0
  155. cgmpy-0.5.2/examples/01_quickstart/basic_analysis.py +56 -0
  156. cgmpy-0.5.2/examples/02_pregnancy/gestational_diabetes.py +61 -0
  157. cgmpy-0.5.2/examples/03_agata_comparison/comparison.py +121 -0
  158. cgmpy-0.5.2/examples/04_performance/benchmark.py +82 -0
  159. cgmpy-0.5.2/examples/README.md +52 -0
  160. cgmpy-0.5.2/mkdocs.yml +187 -0
  161. cgmpy-0.5.2/pyproject.toml +232 -0
  162. cgmpy-0.5.2/scripts/build-dist.ps1 +101 -0
  163. cgmpy-0.5.2/scripts/build-dist.sh +90 -0
  164. cgmpy-0.5.2/scripts/check_docs_sync.py +52 -0
  165. cgmpy-0.5.2/scripts/container-init.sh +42 -0
  166. cgmpy-0.5.2/scripts/generate_fixtures_v052.py +254 -0
  167. cgmpy-0.5.2/scripts/publish-prod.ps1 +50 -0
  168. cgmpy-0.5.2/scripts/publish-prod.sh +58 -0
  169. cgmpy-0.5.2/scripts/publish-test.ps1 +60 -0
  170. cgmpy-0.5.2/scripts/publish-test.sh +60 -0
  171. cgmpy-0.5.2/setup.cfg +4 -0
  172. cgmpy-0.5.2/tests/__init__.py +4 -0
  173. cgmpy-0.5.2/tests/agata/test_agata.py +11 -0
  174. cgmpy-0.5.2/tests/clinical/__init__.py +1 -0
  175. cgmpy-0.5.2/tests/clinical/test_basic_metrics_reference.py +176 -0
  176. cgmpy-0.5.2/tests/clinical/test_variability_reference.py +232 -0
  177. cgmpy-0.5.2/tests/conftest.py +50 -0
  178. cgmpy-0.5.2/tests/fixtures/data/dm.csv +3548 -0
  179. cgmpy-0.5.2/tests/fixtures/data/nodm.csv +2106 -0
  180. cgmpy-0.5.2/tests/fixtures/data/pregnancy.csv +173688 -0
  181. cgmpy-0.5.2/tests/fixtures/devices/dexcom_constant_120.csv +289 -0
  182. cgmpy-0.5.2/tests/fixtures/devices/edge_cases/all_nan_glucose.csv +13 -0
  183. cgmpy-0.5.2/tests/fixtures/devices/edge_cases/empty.csv +1 -0
  184. cgmpy-0.5.2/tests/fixtures/devices/edge_cases/out_of_range_high.csv +13 -0
  185. cgmpy-0.5.2/tests/fixtures/devices/edge_cases/out_of_range_low.csv +13 -0
  186. cgmpy-0.5.2/tests/fixtures/devices/edge_cases/single_row.csv +2 -0
  187. cgmpy-0.5.2/tests/fixtures/devices/edge_cases/with_gap.csv +13 -0
  188. cgmpy-0.5.2/tests/fixtures/devices/libreview_constant_120.csv +291 -0
  189. cgmpy-0.5.2/tests/fixtures/devices/medtronic_constant_120.csv +289 -0
  190. cgmpy-0.5.2/tests/fixtures/devices/tandem_constant_120.csv +289 -0
  191. cgmpy-0.5.2/tests/fixtures/synthetic/sine_24h.csv +289 -0
  192. cgmpy-0.5.2/tests/integration/__init__.py +1 -0
  193. cgmpy-0.5.2/tests/integration/test_data_pipeline.py +55 -0
  194. cgmpy-0.5.2/tests/integration/test_data_to_agata.py +294 -0
  195. cgmpy-0.5.2/tests/unit/__init__.py +1 -0
  196. cgmpy-0.5.2/tests/unit/test_agata/__init__.py +1 -0
  197. cgmpy-0.5.2/tests/unit/test_agata/test_adapter.py +92 -0
  198. cgmpy-0.5.2/tests/unit/test_agata/test_adapter_edge_cases.py +59 -0
  199. cgmpy-0.5.2/tests/unit/test_agata/test_metrics.py +154 -0
  200. cgmpy-0.5.2/tests/unit/test_agata/test_metrics_errors.py +209 -0
  201. cgmpy-0.5.2/tests/unit/test_analysis/__init__.py +1 -0
  202. cgmpy-0.5.2/tests/unit/test_analysis/test_core.py +288 -0
  203. cgmpy-0.5.2/tests/unit/test_data/__init__.py +1 -0
  204. cgmpy-0.5.2/tests/unit/test_data/test_errors.py +521 -0
  205. cgmpy-0.5.2/tests/unit/test_data/test_exporter.py +351 -0
  206. cgmpy-0.5.2/tests/unit/test_data/test_loader.py +67 -0
  207. cgmpy-0.5.2/tests/unit/test_data/test_pregnancy_data.py +305 -0
  208. cgmpy-0.5.2/tests/unit/test_data/test_processor.py +54 -0
  209. cgmpy-0.5.2/tests/unit/test_data/test_specialized.py +259 -0
  210. cgmpy-0.5.2/tests/unit/test_data/test_synthetic_metrics.py +386 -0
  211. cgmpy-0.5.2/tests/unit/test_metrics/__init__.py +1 -0
  212. cgmpy-0.5.2/tests/unit/test_metrics/test_basic_functions.py +75 -0
  213. cgmpy-0.5.2/tests/unit/test_metrics/test_basic_metrics.py +73 -0
  214. cgmpy-0.5.2/tests/unit/test_metrics/test_mage_functions.py +102 -0
  215. cgmpy-0.5.2/tests/unit/test_metrics/test_pregnancy.py +150 -0
  216. cgmpy-0.5.2/tests/unit/test_metrics/test_risk_functions.py +110 -0
  217. cgmpy-0.5.2/tests/unit/test_metrics/test_sd_functions.py +405 -0
  218. cgmpy-0.5.2/tests/unit/test_metrics/test_targets.py +85 -0
  219. cgmpy-0.5.2/tests/unit/test_metrics/test_time_in_range_functions.py +115 -0
  220. cgmpy-0.5.2/tests/unit/test_metrics/test_units.py +64 -0
  221. cgmpy-0.5.2/tests/unit/test_metrics/test_validation.py +92 -0
  222. cgmpy-0.5.2/tests/unit/test_metrics/test_variability_functions.py +92 -0
  223. cgmpy-0.5.2/tests/unit/test_metrics/test_variability_metrics.py +69 -0
  224. cgmpy-0.5.2/tests/unit/test_metrics/variability/__init__.py +0 -0
  225. cgmpy-0.5.2/tests/unit/test_metrics/variability/test_facade.py +138 -0
  226. cgmpy-0.5.2/tests/unit/test_metrics/variability/test_mage.py +104 -0
  227. cgmpy-0.5.2/tests/unit/test_metrics/variability/test_risk.py +123 -0
  228. cgmpy-0.5.2/tests/unit/test_metrics/variability/test_sd.py +266 -0
  229. cgmpy-0.5.2/tests/unit/test_plotting/__init__.py +0 -0
  230. cgmpy-0.5.2/tests/unit/test_plotting/conftest.py +46 -0
  231. cgmpy-0.5.2/tests/unit/test_plotting/test_agp.py +221 -0
  232. cgmpy-0.5.2/tests/unit/test_plotting/test_daily_plots.py +229 -0
  233. cgmpy-0.5.2/tests/unit/test_plotting/test_statistical_plots.py +308 -0
  234. cgmpy-0.5.2/tests/unit/test_utils/__init__.py +1 -0
  235. cgmpy-0.5.2/tests/unit/test_utils/test_date_utils.py +225 -0
  236. cgmpy-0.5.2/tests/unit/test_v051_regressions.py +257 -0
@@ -0,0 +1,56 @@
1
+ root = true
2
+
3
+ # Universal defaults for all files
4
+ [*]
5
+ charset = utf-8
6
+ end_of_line = lf
7
+ insert_final_newline = true
8
+ trim_trailing_whitespace = true
9
+
10
+ # Python source code
11
+ [*.py]
12
+ indent_style = space
13
+ indent_size = 4
14
+ max_line_length = 100
15
+
16
+ # Python config files
17
+ [{pyproject.toml,setup.cfg,tox.ini}]
18
+ indent_style = space
19
+ indent_size = 4
20
+
21
+ # JSON and config files
22
+ [*.{json,jsonc}]
23
+ indent_style = space
24
+ indent_size = 2
25
+
26
+ # YAML / TOML
27
+ [*.{yml,yaml,toml}]
28
+ indent_style = space
29
+ indent_size = 2
30
+
31
+ # Markdown — preserve trailing whitespace (significant in some dialects)
32
+ [*.md]
33
+ trim_trailing_whitespace = false
34
+ max_line_length = off
35
+
36
+ # Shell scripts
37
+ [*.{sh,bash}]
38
+ indent_style = space
39
+ indent_size = 2
40
+
41
+ # Windows batch files — LF for cross-platform CI/Docker
42
+ [*.{bat,cmd}]
43
+ end_of_line = lf
44
+
45
+ # PowerShell scripts — LF enforced
46
+ [*.ps1]
47
+ end_of_line = lf
48
+
49
+ # Makefile — tabs are semantic
50
+ [{Makefile,makefile,*.mk}]
51
+ indent_style = tab
52
+
53
+ # Lock files — generated, minimize diff noise
54
+ [{uv.lock,package-lock.json,package-lock.yaml,poetry.lock}]
55
+ indent_style = space
56
+ insert_final_newline = true
@@ -0,0 +1,70 @@
1
+ # GitAttributes — Line Ending & Diff Governance
2
+ # https://git-scm.com/docs/gitattributes
3
+ #
4
+ # CGMPy enforces LF for all text files to ensure consistent
5
+ # cross-platform behavior in CI/CD, packaging, and tooling.
6
+
7
+ # ------------------------------------------------------------------
8
+ # Default: auto-detect text, force LF
9
+ # ------------------------------------------------------------------
10
+ * text=auto eol=lf
11
+
12
+ # ------------------------------------------------------------------
13
+ # Source code — explicit text declaration
14
+ # ------------------------------------------------------------------
15
+ *.py text eol=lf
16
+ *.toml text eol=lf
17
+ *.json text eol=lf
18
+ *.jsonc text eol=lf
19
+ *.yml text eol=lf
20
+ *.yaml text eol=lf
21
+ *.md text eol=lf
22
+ *.rst text eol=lf
23
+ *.txt text eol=lf
24
+ *.cfg text eol=lf
25
+ *.ini text eol=lf
26
+
27
+ # Windows scripts — LF enforced for cross-platform CI/Docker
28
+ # (PowerShell and modern cmd.exe handle LF correctly)
29
+ *.bat text eol=lf
30
+ *.cmd text eol=lf
31
+ *.ps1 text eol=lf
32
+
33
+ # ------------------------------------------------------------------
34
+ # Binary assets — do not modify, do not diff as text
35
+ # ------------------------------------------------------------------
36
+ *.png binary
37
+ *.jpg binary
38
+ *.jpeg binary
39
+ *.gif binary
40
+ *.ico binary
41
+ *.icns binary
42
+ *.svg text eol=lf
43
+ *.woff binary
44
+ *.woff2 binary
45
+ *.ttf binary
46
+ *.eot binary
47
+ *.pdf binary
48
+ *.pkl binary
49
+ *.db binary
50
+ *.parquet binary
51
+ *.h5 binary
52
+ *.hdf5 binary
53
+ *.feather binary
54
+ *.zip binary
55
+ *.tar binary
56
+ *.gz binary
57
+ *.7z binary
58
+ *.whl binary
59
+ *.egg binary
60
+ *.exe binary
61
+ *.dll binary
62
+ *.so binary
63
+ *.dylib binary
64
+
65
+ # ------------------------------------------------------------------
66
+ # Lock files — generated, minimize diff noise on GitHub
67
+ # ------------------------------------------------------------------
68
+ uv.lock linguist-generated=true
69
+ poetry.lock linguist-generated=true
70
+ package-lock.json linguist-generated=true
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report a bug to help CGMPy improve
4
+ title: "[Bug]: "
5
+ labels: ["bug", "needs-triage"]
6
+ assignees: []
7
+ ---
8
+
9
+ ## 🐛 Bug Description
10
+
11
+ A clear and concise description of what the bug is.
12
+
13
+ ## 📋 Reproduction
14
+
15
+ Minimal, complete example to reproduce the issue:
16
+
17
+ ```python
18
+ # Paste your code here
19
+ ```
20
+
21
+ ## 📊 Data (anonymized!)
22
+
23
+ If the bug requires specific data:
24
+
25
+ - **Is the data synthetic or anonymized?** (required — see [SECURITY.md](../SECURITY.md))
26
+ - **What format is it in?** (CSV, Parquet, DataFrame)
27
+ - **How many rows / time span?**
28
+ - **What device does it come from?** (Dexcom, Libre, ...)
29
+
30
+ > ⚠️ **DO NOT paste real CGM data, even if you think it's anonymous.** Use `python scripts/anonymize_cgm.py` first.
31
+
32
+ ## ✅ Expected Behavior
33
+
34
+ What you expected to happen.
35
+
36
+ ## ❌ Actual Behavior
37
+
38
+ What actually happened. Include the full traceback:
39
+
40
+ ```
41
+ Paste the full traceback here
42
+ ```
43
+
44
+ ## 🖥️ Environment
45
+
46
+ - **OS**: (e.g., Windows 11, macOS 14, Ubuntu 22.04)
47
+ - **Python version**: (output of `python --version`)
48
+ - **CGMPy version**: (output of `pip show cgmpy`)
49
+ - **Install method**: (pip, uv, from source)
50
+ - **Optional dependencies installed**: (e.g., `agata`, `pyarrow` version)
51
+
52
+ ## 📝 Additional Context
53
+
54
+ Add any other context, screenshots, or links here.
55
+
56
+ ## ✅ Checklist
57
+
58
+ - [ ] I have searched the [existing issues](../../issues) for this bug.
59
+ - [ ] I have read [SECURITY.md](../SECURITY.md) and will **not** include real patient data.
60
+ - [ ] I am using the latest released version of CGMPy (or the latest `main`).
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest a new feature for CGMPy
4
+ title: "[Feature]: "
5
+ labels: ["enhancement", "needs-triage"]
6
+ assignees: []
7
+ ---
8
+
9
+ ## 🚀 Feature Description
10
+
11
+ A clear and concise description of the feature you want.
12
+
13
+ ## 💡 Motivation
14
+
15
+ What problem does this solve? Why is it useful for clinical or research workflows?
16
+
17
+ ## 📐 Proposed API
18
+
19
+ If you have an idea of the API, sketch it out:
20
+
21
+ ```python
22
+ # Example usage
23
+ from cgmpy.metrics import ...
24
+
25
+ result = ...
26
+ ```
27
+
28
+ ## 🔗 References
29
+
30
+ - Clinical / academic reference (paper, DOI, URL)
31
+ - Similar feature in another library (e.g., R's `iglu`, Python's `agata`)
32
+ - Related issue or discussion
33
+
34
+ ## 🎯 Acceptance Criteria
35
+
36
+ - [ ] The metric / loader / plot is implemented.
37
+ - [ ] Unit tests are added (with a known-answer dataset).
38
+ - [ ] Clinical regression test is added (if a published reference exists).
39
+ - [ ] Documentation is updated (`docs/user-guide/...`).
40
+ - [ ] `CHANGELOG.md` `[Unreleased]` is updated.
41
+ - [ ] AGATA parity is checked (if applicable).
42
+
43
+ ## 📊 Priority
44
+
45
+ How important is this for your work?
46
+
47
+ - [ ] Blocking my work / study.
48
+ - [ ] Would significantly improve my workflow.
49
+ - [ ] Nice to have.
50
+
51
+ ## ✅ Checklist
52
+
53
+ - [ ] I have searched the [existing issues](../../issues) for a similar request.
54
+ - [ ] I am willing to submit a PR for this feature (or a draft of it).
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: Question
3
+ about: Ask a question about CGMPy
4
+ title: "[Question]: "
5
+ labels: ["question"]
6
+ assignees: []
7
+ ---
8
+
9
+ ## ❓ Question
10
+
11
+ A clear, focused question. If you have multiple, please open multiple issues.
12
+
13
+ ## 📖 What I've Tried
14
+
15
+ - [ ] Read the [README](../README.md)
16
+ - [ ] Read the [docs/](../docs/)
17
+ - [ ] Searched [existing issues](../../issues) and [discussions](../../discussions)
18
+ - [ ] Searched the [CHANGELOG](../CHANGELOG.md) for breaking changes
19
+
20
+ ## 🖥️ Environment (if relevant)
21
+
22
+ - **OS**: ...
23
+ - **Python version**: ...
24
+ - **CGMPy version**: ...
25
+
26
+ ## 📝 Additional Context
27
+
28
+ Code snippets, screenshots, or links that help explain the question.
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: Pull Request
3
+ about: Submit changes to CGMPy
4
+ title: "[<type>(<scope>)]: <description>"
5
+ ---
6
+
7
+ ## 📋 Summary
8
+
9
+ <!-- Replace this line with a one-paragraph summary of what this PR does. -->
10
+
11
+ ## 🎯 Motivation
12
+
13
+ <!-- Why is this change needed? What problem does it solve? -->
14
+
15
+ ## 🔧 Changes
16
+
17
+ <!-- Bullet list of the main changes. -->
18
+
19
+ - ...
20
+
21
+ ## 📸 Screenshots / Outputs
22
+
23
+ <!-- If the change affects plots, reports, or UI, include a screenshot or paste the relevant output. -->
24
+
25
+ ## 🧪 Testing
26
+
27
+ - [ ] I have added or updated unit tests.
28
+ - [ ] I have added a clinical regression test (if a published reference exists).
29
+ - [ ] I have checked AGATA parity (if applicable).
30
+ - [ ] I have run `make lint` and `make test` locally — all pass.
31
+
32
+ ## 📚 Documentation
33
+
34
+ Per the [Documentation Golden Rule](../AGENTS.md) §3:
35
+
36
+ - [ ] `docs/user-guide/...` updated (if user-facing).
37
+ - [ ] `docs/api/...` regenerated (auto, on next build).
38
+ - [ ] `CHANGELOG.md` `[Unreleased]` updated (if user-facing).
39
+ - [ ] Docstrings added / updated for new public symbols.
40
+
41
+ ## 🔒 Security
42
+
43
+ - [ ] No PHI in code, tests, examples, or fixtures.
44
+ - [ ] No hardcoded credentials or secrets.
45
+ - [ ] No new dependencies without justification.
46
+
47
+ ## ⚠️ Breaking Changes
48
+
49
+ <!-- If this PR introduces breaking changes, describe the migration path. -->
50
+
51
+ - [ ] No breaking changes.
52
+ - [ ] Breaking change described above, with migration notes.
53
+
54
+ ## 📎 Related Issues
55
+
56
+ <!-- Use keywords to auto-close: Closes #N, Fixes #N, Relates to #N -->
57
+
58
+ Closes #
59
+
60
+ ## ✅ Pre-Submit Checklist
61
+
62
+ - [ ] I have read [CONTRIBUTING.md](../CONTRIBUTING.md).
63
+ - [ ] My branch is up to date with `main` (`git fetch && git rebase origin/main`).
64
+ - [ ] My commit messages follow [Conventional Commits](https://www.conventionalcommits.org/).
65
+ - [ ] The PR title follows Conventional Commits (verified by CI).
66
+ - [ ] I have run `make pre-commit-all` — all hooks pass.
67
+ - [ ] I have updated relevant tests and documentation.
@@ -0,0 +1,42 @@
1
+ version: 2
2
+ updates:
3
+ # Python dependencies (pyproject.toml)
4
+ - package-ecosystem: "pip"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "weekly"
8
+ day: "monday"
9
+ time: "06:00"
10
+ open-pull-requests-limit: 10
11
+ labels:
12
+ - "dependencies"
13
+ - "python"
14
+ groups:
15
+ # Group patch + minor updates into one PR
16
+ python-minor:
17
+ patterns:
18
+ - "*"
19
+ update-types:
20
+ - "minor"
21
+ - "patch"
22
+ # Major updates are surfaced separately
23
+ python-major:
24
+ patterns:
25
+ - "*"
26
+ update-types:
27
+ - "major"
28
+ commit-message:
29
+ prefix: "chore(deps)"
30
+
31
+ # GitHub Actions
32
+ - package-ecosystem: "github-actions"
33
+ directory: "/"
34
+ schedule:
35
+ interval: "weekly"
36
+ day: "tuesday"
37
+ open-pull-requests-limit: 5
38
+ labels:
39
+ - "dependencies"
40
+ - "ci"
41
+ commit-message:
42
+ prefix: "ci(actions)"
@@ -0,0 +1,39 @@
1
+ "area/data":
2
+ - cgmpy/data/**
3
+ "area/metrics":
4
+ - cgmpy/metrics/**
5
+ "area/plotting":
6
+ - cgmpy/plotting/**
7
+ "area/analysis":
8
+ - cgmpy/analysis/**
9
+ "area/agata":
10
+ - cgmpy/agata/**
11
+
12
+ "docs":
13
+ - docs/**
14
+ - "**/*.md"
15
+ - "**/*.rst"
16
+
17
+ "tests":
18
+ - tests/**
19
+
20
+ "examples":
21
+ - examples/**
22
+
23
+ "ci":
24
+ - .github/**
25
+ - .pre-commit-config.yaml
26
+ - Makefile
27
+
28
+ "tooling":
29
+ - pyproject.toml
30
+ - commitlint.config.cjs
31
+ - .editorconfig
32
+ - .gitattributes
33
+ - .gitignore
34
+ - .gitmessage
35
+
36
+ "agents":
37
+ - .opencode/**
38
+ - AGENTS.md
39
+ - .geminiignore
@@ -0,0 +1,47 @@
1
+ name: Check Line Endings
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ check-line-endings:
15
+ name: Enforce LF
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - name: Checkout
19
+ uses: actions/checkout@v6
20
+ with:
21
+ fetch-depth: 0
22
+
23
+ - name: Check for CRLF
24
+ run: |
25
+ echo "Checking for CRLF line endings in tracked files..."
26
+ # Find any tracked file that contains CRLF.
27
+ # `|| true` masks xargs's exit 123 when no sub-sh returns 0 (i.e. no
28
+ # files match). The real failure is decided by [ -n "$BAD" ] below.
29
+ BAD=$(git ls-files -z | xargs -0 -I {} sh -c 'file "{}" 2>/dev/null | grep -q CRLF && echo "{}"' 2>/dev/null || true)
30
+ if [ -n "$BAD" ]; then
31
+ echo "::error::The following files have CRLF line endings (should be LF):"
32
+ echo "$BAD"
33
+ exit 1
34
+ fi
35
+ echo "✅ All tracked files use LF line endings."
36
+
37
+ - name: Check for BOM
38
+ run: |
39
+ echo "Checking for UTF-8 BOM in tracked files..."
40
+ # See CRLF step above for the `|| true` rationale.
41
+ BAD=$(git ls-files -z | xargs -0 -I {} sh -c 'head -c 3 "{}" 2>/dev/null | xxd | grep -q "efbbbf" && echo "{}"' 2>/dev/null || true)
42
+ if [ -n "$BAD" ]; then
43
+ echo "::error::The following files have a UTF-8 BOM (should not):"
44
+ echo "$BAD"
45
+ exit 1
46
+ fi
47
+ echo "✅ No tracked files have a UTF-8 BOM."
@@ -0,0 +1,149 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ workflow_dispatch:
9
+
10
+ # Cancel in-progress runs for the same branch on new pushes
11
+ concurrency:
12
+ group: ci-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ # ------------------------------------------------------------------
20
+ # Lint & format (fast feedback)
21
+ # ------------------------------------------------------------------
22
+ lint:
23
+ name: Lint & format
24
+ runs-on: ubuntu-latest
25
+ steps:
26
+ - name: Checkout
27
+ uses: actions/checkout@v6
28
+
29
+ - name: Setup Python
30
+ uses: actions/setup-python@v6
31
+ with:
32
+ python-version: "3.12"
33
+
34
+ - name: Install ruff + mypy
35
+ run: pip install "ruff>=0.6" mypy
36
+
37
+ - name: ruff check
38
+ run: ruff check .
39
+
40
+ - name: ruff format check
41
+ run: ruff format --check .
42
+
43
+ - name: mypy
44
+ run: mypy cgmpy
45
+
46
+ # ------------------------------------------------------------------
47
+ # Security audit + pre-commit
48
+ # ------------------------------------------------------------------
49
+ security:
50
+ name: Security audit
51
+ runs-on: ubuntu-latest
52
+ steps:
53
+ - name: Checkout
54
+ uses: actions/checkout@v6
55
+
56
+ - name: Setup Python
57
+ uses: actions/setup-python@v6
58
+ with:
59
+ python-version: "3.12"
60
+
61
+ - name: Install bandit + pip-audit + pre-commit
62
+ run: pip install "bandit[toml]>=1.7" pip-audit pre-commit
63
+
64
+ - name: Bandit
65
+ run: bandit -r cgmpy/ -ll
66
+
67
+ - name: pip-audit
68
+ # Block on known-vulnerable dependencies. CGMPy handles medical
69
+ # data; a "warning" here is not a soft signal. If a transitive
70
+ # dependency is flagged, fix it (pin a safe version, replace,
71
+ # or open an issue) — do not silence the failure.
72
+ run: pip-audit
73
+
74
+ - name: pre-commit
75
+ run: pre-commit run --all-files --show-diff-on-failure
76
+
77
+ # ------------------------------------------------------------------
78
+ # Test matrix (multi-OS, multi-Python)
79
+ # ------------------------------------------------------------------
80
+ test:
81
+ name: Tests (${{ matrix.os }} · py${{ matrix.python-version }})
82
+ runs-on: ${{ matrix.os }}
83
+ strategy:
84
+ fail-fast: false
85
+ matrix:
86
+ os: [ubuntu-latest, windows-latest, macos-latest]
87
+ python-version: ["3.10", "3.11", "3.12"]
88
+
89
+ steps:
90
+ - name: Checkout
91
+ uses: actions/checkout@v6
92
+
93
+ - name: Setup Python ${{ matrix.python-version }}
94
+ uses: actions/setup-python@v6
95
+ with:
96
+ python-version: ${{ matrix.python-version }}
97
+ cache: pip
98
+
99
+ - name: Install package + dev deps
100
+ run: |
101
+ python -m pip install --upgrade pip
102
+ pip install -e ".[dev,agata]"
103
+
104
+ - name: Run tests
105
+ run: pytest -v --color=yes
106
+
107
+ - name: Upload coverage (Linux only)
108
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
109
+ uses: codecov/codecov-action@v6
110
+ with:
111
+ files: ./coverage.xml
112
+ flags: unittests
113
+ name: codecov-${{ matrix.os }}-py${{ matrix.python-version }}
114
+ fail_ci_if_error: false
115
+ env:
116
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
117
+
118
+ # ------------------------------------------------------------------
119
+ # Test with coverage (Linux + py3.12, generates coverage.xml)
120
+ # ------------------------------------------------------------------
121
+ coverage:
122
+ name: Coverage report
123
+ runs-on: ubuntu-latest
124
+ needs: [lint, test]
125
+ steps:
126
+ - name: Checkout
127
+ uses: actions/checkout@v6
128
+
129
+ - name: Setup Python
130
+ uses: actions/setup-python@v6
131
+ with:
132
+ python-version: "3.12"
133
+ cache: pip
134
+
135
+ - name: Install package + dev deps
136
+ run: |
137
+ python -m pip install --upgrade pip
138
+ pip install -e ".[dev,agata]"
139
+
140
+ - name: Run tests with coverage
141
+ run: pytest --cov=cgmpy --cov-report=xml --cov-report=term-missing
142
+
143
+ - name: Upload coverage to Codecov
144
+ uses: codecov/codecov-action@v6
145
+ with:
146
+ file: ./coverage.xml
147
+ fail_ci_if_error: false
148
+ env:
149
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
@@ -0,0 +1,43 @@
1
+ name: CodeQL
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ schedule:
9
+ # Run weekly on Mondays at 04:00 UTC
10
+ - cron: "0 4 * * 1"
11
+ workflow_dispatch:
12
+
13
+ permissions:
14
+ actions: read
15
+ contents: read
16
+ security-events: write
17
+
18
+ jobs:
19
+ analyze:
20
+ name: CodeQL (${{ matrix.language }})
21
+ runs-on: ubuntu-latest
22
+ strategy:
23
+ fail-fast: false
24
+ matrix:
25
+ include:
26
+ - language: python
27
+ build-mode: none
28
+
29
+ steps:
30
+ - name: Checkout
31
+ uses: actions/checkout@v6
32
+
33
+ - name: Initialize CodeQL
34
+ uses: github/codeql-action/init@v4
35
+ with:
36
+ languages: ${{ matrix.language }}
37
+ build-mode: ${{ matrix.build-mode }}
38
+ queries: security-and-quality
39
+
40
+ - name: Perform CodeQL Analysis
41
+ uses: github/codeql-action/analyze@v4
42
+ with:
43
+ category: "/language:${{ matrix.language }}"