cellpy 2.1.2a3__tar.gz → 2.1.2a4__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 (453) hide show
  1. cellpy-2.1.2a4/.issueflows/03-solved-issues/issue862_original.md +45 -0
  2. cellpy-2.1.2a4/.issueflows/03-solved-issues/issue862_plan.md +90 -0
  3. cellpy-2.1.2a4/.issueflows/03-solved-issues/issue862_status.md +28 -0
  4. cellpy-2.1.2a4/.issueflows/03-solved-issues/issue863_original.md +35 -0
  5. cellpy-2.1.2a4/.issueflows/03-solved-issues/issue863_plan.md +103 -0
  6. cellpy-2.1.2a4/.issueflows/03-solved-issues/issue863_status.md +33 -0
  7. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/test-registry.md +8 -0
  8. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/HISTORY.md +2 -0
  9. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/PKG-INFO +1 -1
  10. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/collect/__init__.py +4 -0
  11. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/collect/collection.py +2 -2
  12. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/collect/collector.py +8 -0
  13. cellpy-2.1.2a4/cellpy/collect/dva.py +95 -0
  14. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/collect/options.py +10 -1
  15. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/ica.py +30 -55
  16. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/backends/mpl.py +13 -4
  17. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/backends/plotly.py +12 -4
  18. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/collected.py +77 -1
  19. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/config_declarations.py +8 -8
  20. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.aliases +0 -0
  21. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/commands/build.md +0 -0
  22. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/commands/create-original-issue-file.md +0 -0
  23. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/rules/cellpy-core-migration.mdc +0 -0
  24. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/rules/cellpy-workspace.mdc +0 -0
  25. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/rules/graphify.mdc +0 -0
  26. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/rules/issueflow-rules.mdc +0 -0
  27. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/rules/kiss.mdc +0 -0
  28. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/rules/this-project.mdc +0 -0
  29. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/caveman/SKILL.md +0 -0
  30. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/gh-ci/SKILL.md +0 -0
  31. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/grill-me/SKILL.md +0 -0
  32. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow/SKILL.md +0 -0
  33. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-archive/SKILL.md +0 -0
  34. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-auto/SKILL.md +0 -0
  35. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-build/SKILL.md +0 -0
  36. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-cleanup/SKILL.md +0 -0
  37. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-close/SKILL.md +0 -0
  38. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-comments/SKILL.md +0 -0
  39. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-cycle/SKILL.md +0 -0
  40. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-doctor/SKILL.md +0 -0
  41. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-epic/SKILL.md +0 -0
  42. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-fix/SKILL.md +0 -0
  43. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-graphify/SKILL.md +0 -0
  44. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-history-update/SKILL.md +0 -0
  45. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-init/SKILL.md +0 -0
  46. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-issue/SKILL.md +0 -0
  47. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-pause/SKILL.md +0 -0
  48. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-pick/SKILL.md +0 -0
  49. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-plan/SKILL.md +0 -0
  50. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-review/SKILL.md +0 -0
  51. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-status/SKILL.md +0 -0
  52. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-version-bump/SKILL.md +0 -0
  53. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/iflow-yolo/SKILL.md +0 -0
  54. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.cursor/skills/issueflow-build/SKILL.md +0 -0
  55. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.dockerignore +0 -0
  56. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.editorconfig +0 -0
  57. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.env_example +0 -0
  58. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.gitattributes +0 -0
  59. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.gitignore +0 -0
  60. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/00-tools/.gitkeep +0 -0
  61. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/00-tools/README.md +0 -0
  62. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/00-tools/migrate_prms_calls.py +0 -0
  63. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/00-tools/scan_hardcoded_headers.py +0 -0
  64. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/00-tools/scan_member_usage.py +0 -0
  65. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/01-current-issues/.gitkeep +0 -0
  66. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/02-partly-solved-issues/.gitkeep +0 -0
  67. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/.gitkeep +0 -0
  68. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/2026-07-09_archived_issues.md +0 -0
  69. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/2026-07-31_archived_issues.md +0 -0
  70. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/cycle_status_2026-07-31.md +0 -0
  71. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/cycle_status_2026-08-08.md +0 -0
  72. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/cycle_status_2026-08-09.md +0 -0
  73. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue459_original.md +0 -0
  74. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue786_original.md +0 -0
  75. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue786_plan.md +0 -0
  76. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue786_status.md +0 -0
  77. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue799_original.md +0 -0
  78. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue799_plan.md +0 -0
  79. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue799_status.md +0 -0
  80. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue800_original.md +0 -0
  81. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue800_plan.md +0 -0
  82. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue800_status.md +0 -0
  83. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue801_original.md +0 -0
  84. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue801_plan.md +0 -0
  85. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue801_status.md +0 -0
  86. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue802_original.md +0 -0
  87. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue802_plan.md +0 -0
  88. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue802_status.md +0 -0
  89. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue804_original.md +0 -0
  90. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue804_plan.md +0 -0
  91. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue804_status.md +0 -0
  92. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue809_original.md +0 -0
  93. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue809_plan.md +0 -0
  94. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue809_status.md +0 -0
  95. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue816_original.md +0 -0
  96. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue816_plan.md +0 -0
  97. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue816_status.md +0 -0
  98. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue817_original.md +0 -0
  99. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue817_plan.md +0 -0
  100. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue817_status.md +0 -0
  101. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue818_original.md +0 -0
  102. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue818_plan.md +0 -0
  103. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue818_status.md +0 -0
  104. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue819_original.md +0 -0
  105. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue819_plan.md +0 -0
  106. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue819_status.md +0 -0
  107. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue820_original.md +0 -0
  108. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue820_plan.md +0 -0
  109. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue820_status.md +0 -0
  110. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue821_original.md +0 -0
  111. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue821_plan.md +0 -0
  112. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue821_status.md +0 -0
  113. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue822_original.md +0 -0
  114. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue822_plan.md +0 -0
  115. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue822_status.md +0 -0
  116. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue825_original.md +0 -0
  117. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue825_plan.md +0 -0
  118. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue825_status.md +0 -0
  119. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue837_original.md +0 -0
  120. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue837_plan.md +0 -0
  121. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue837_status.md +0 -0
  122. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue839_original.md +0 -0
  123. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue839_plan.md +0 -0
  124. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue839_status.md +0 -0
  125. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue845_original.md +0 -0
  126. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue845_plan.md +0 -0
  127. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue845_status.md +0 -0
  128. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue846_original.md +0 -0
  129. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue846_plan.md +0 -0
  130. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue846_status.md +0 -0
  131. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue849_original.md +0 -0
  132. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue849_plan.md +0 -0
  133. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue849_status.md +0 -0
  134. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue850_original.md +0 -0
  135. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue850_plan.md +0 -0
  136. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue850_status.md +0 -0
  137. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue851_original.md +0 -0
  138. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue851_plan.md +0 -0
  139. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue851_status.md +0 -0
  140. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue853_original.md +0 -0
  141. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue853_plan.md +0 -0
  142. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue853_status.md +0 -0
  143. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue855_original.md +0 -0
  144. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue855_plan.md +0 -0
  145. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/03-solved-issues/issue855_status.md +0 -0
  146. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/.gitkeep +0 -0
  147. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/atomic-file-writes.md +0 -0
  148. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/batch-load-orchestrator.md +0 -0
  149. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/bdf-export.md +0 -0
  150. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/build-and-versioning.md +0 -0
  151. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/cellpy-v2-architecture.excalidraw +0 -0
  152. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/cellpy-v2-branching.md +0 -0
  153. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/cellpy-v2-epic.md +0 -0
  154. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/cellpy-workspace-repos.md +0 -0
  155. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/cellpycell-di-restructuring.md +0 -0
  156. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/ci-tiers.md +0 -0
  157. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/cli-api-echo-binder.md +0 -0
  158. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/cli-light-startup.md +0 -0
  159. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/docs-on-master.md +0 -0
  160. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/essential-tests.md +0 -0
  161. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/filters-and-plot-filtering.md +0 -0
  162. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/harmonized-raw-default.md +0 -0
  163. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/marimo-docs.md +0 -0
  164. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/otherpath-upath.md +0 -0
  165. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/plotting-backends.md +0 -0
  166. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/plotting-batch-summary.md +0 -0
  167. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/plotting-collected.md +0 -0
  168. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/plotting-cycle-legend.md +0 -0
  169. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/plotting-prepare.md +0 -0
  170. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/plotting-registry.md +0 -0
  171. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/release-procedure.md +0 -0
  172. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/testing-and-coverage.md +0 -0
  173. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/this-project.md +0 -0
  174. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/04-designs-and-guides/v2-cellpycore-pin-gate.md +0 -0
  175. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/05-epics/.gitkeep +0 -0
  176. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/05-epics/epic567_plan.md +0 -0
  177. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.issueflows/config.toml +0 -0
  178. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/.readthedocs.yaml +0 -0
  179. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/AGENTS.md +0 -0
  180. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/AUTHORS.md +0 -0
  181. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/CODE_OF_CONDUCT.md +0 -0
  182. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/CONTRIBUTING.md +0 -0
  183. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/DEPRECATIONS.md +0 -0
  184. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/LICENSE.md +0 -0
  185. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/README.md +0 -0
  186. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_developers_guide/dev_cellpy_data_structure.md +0 -0
  187. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_developers_guide/dev_cellpy_folder_structure.md +0 -0
  188. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_developers_guide/dev_cellpy_packaging_pypi.md +0 -0
  189. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_developers_guide/dev_cellpy_setup.md +0 -0
  190. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_developers_guide/dev_conda_package.md +0 -0
  191. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_developers_guide/dev_docs.md +0 -0
  192. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_developers_guide/dev_loaders_and_instruments.md +0 -0
  193. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_developers_guide/dev_various.md +0 -0
  194. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_developers_guide/index.md +0 -0
  195. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/basic_interactions/01_getting_started_tutorial.md +0 -0
  196. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/basic_interactions/02_read_cell_data.md +0 -0
  197. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/basic_interactions/03_more_about_get.md +0 -0
  198. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/basic_interactions/04_other_interactions.md +0 -0
  199. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/basic_interactions/05_configuring.md +0 -0
  200. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/basic_interactions/06_pandas.md +0 -0
  201. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/basic_interactions/07_data_mining.md +0 -0
  202. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/basic_interactions/08_the_cellpy_cmd.md +0 -0
  203. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/basics.md +0 -0
  204. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/examples.md +0 -0
  205. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/index.md +0 -0
  206. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/loaders/01_arbin.md +0 -0
  207. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/loaders/02_maccor.md +0 -0
  208. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/loaders/03_PEC.md +0 -0
  209. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/loaders/04_Neware.md +0 -0
  210. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/loaders/05_biologics.md +0 -0
  211. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/loaders/06_custom.md +0 -0
  212. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/loaders.md +0 -0
  213. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/notebooks/images/templates_jupyterlab_001.png +0 -0
  214. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/notebooks/images/templates_jupyterlab_002.png +0 -0
  215. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/notebooks/tutorial_get_cap.ipynb +0 -0
  216. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/notebooks/tutorial_simple_plot.ipynb +0 -0
  217. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/notebooks/tutorial_templates.ipynb +0 -0
  218. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/notebooks/tutorial_xxx-checkpoint.ipynb +0 -0
  219. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/notebooks.md +0 -0
  220. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/tips_and_tricks.md +0 -0
  221. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/utils/batch.md +0 -0
  222. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/utils/collectors.md +0 -0
  223. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/utils/custom_file_loaders.md +0 -0
  224. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/utils/easyplot.md +0 -0
  225. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/utils/figures/tutorials_utils_plotting_fig1.png +0 -0
  226. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/utils/figures/tutorials_utils_plotting_fig2.png +0 -0
  227. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/utils/ica.md +0 -0
  228. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/utils/plotting.md +0 -0
  229. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/utils/templates.md +0 -0
  230. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/utils/tut_ocv_rlx.md +0 -0
  231. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_examples_and_tutorials/utils.md +0 -0
  232. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_main_description/formats.md +0 -0
  233. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_main_description/index.md +0 -0
  234. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_main_description/installation.md +0 -0
  235. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/_main_description/usage.md +0 -0
  236. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/_old_docs/index.md +0 -0
  237. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/benchmarks/README.md +0 -0
  238. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/benchmarks/__init__.py +0 -0
  239. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/benchmarks/baselines/v1x_ubuntu_py313.json +0 -0
  240. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/benchmarks/check_baseline.py +0 -0
  241. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/benchmarks/conftest.py +0 -0
  242. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/benchmarks/paths.py +0 -0
  243. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/benchmarks/test_performance.py +0 -0
  244. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/__init__.py +0 -0
  245. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/_deprecation.py +0 -0
  246. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/_version.py +0 -0
  247. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/batch/__init__.py +0 -0
  248. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/batch/_dbengine.py +0 -0
  249. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/batch/aggregate.py +0 -0
  250. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/batch/db.py +0 -0
  251. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/batch/facade.py +0 -0
  252. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/batch/journal.py +0 -0
  253. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/batch/layout.py +0 -0
  254. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/batch/outputs.py +0 -0
  255. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/batch/policy.py +0 -0
  256. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/batch/qc.py +0 -0
  257. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/batch/result.py +0 -0
  258. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/batch/runner.py +0 -0
  259. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/batch/store.py +0 -0
  260. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/cli.py +0 -0
  261. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/cli_api.py +0 -0
  262. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/collect/_summary_ops.py +0 -0
  263. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/collect/cells.py +0 -0
  264. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/collect/curves.py +0 -0
  265. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/collect/ica.py +0 -0
  266. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/collect/summary.py +0 -0
  267. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/config/__init__.py +0 -0
  268. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/config/credentials.py +0 -0
  269. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/config/legacy.py +0 -0
  270. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/config/loader.py +0 -0
  271. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/config/migrate.py +0 -0
  272. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/config/models.py +0 -0
  273. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/config/reference.py +0 -0
  274. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/config/session.py +0 -0
  275. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/config/sources.py +0 -0
  276. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/config/types.py +0 -0
  277. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/exceptions.py +0 -0
  278. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/exporters/__init__.py +0 -0
  279. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/exporters/bdf.py +0 -0
  280. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/exporters/tabular.py +0 -0
  281. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/filters/__init__.py +0 -0
  282. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/filters/cycles.py +0 -0
  283. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/filters/summary.py +0 -0
  284. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/internals/__init__.py +0 -0
  285. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/internals/connections.py +0 -0
  286. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/internals/otherpath.py +0 -0
  287. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/__init__.py +0 -0
  288. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/apipkg/__init__.py +0 -0
  289. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/apipkg/_alias_module.py +0 -0
  290. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/apipkg/_importing.py +0 -0
  291. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/apipkg/_module.py +0 -0
  292. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/apipkg/_syncronized.py +0 -0
  293. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/apipkg/_version.py +0 -0
  294. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/apipkg/py.typed +0 -0
  295. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/local_fastnda/LICENSE +0 -0
  296. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/local_fastnda/__init__.py +0 -0
  297. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/local_fastnda/btsda.py +0 -0
  298. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/local_fastnda/cli.py +0 -0
  299. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/local_fastnda/dicts.py +0 -0
  300. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/local_fastnda/formats.py +0 -0
  301. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/local_fastnda/main.py +0 -0
  302. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/local_fastnda/nda.py +0 -0
  303. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/local_fastnda/ndax.py +0 -0
  304. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/local_fastnda/utils.py +0 -0
  305. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/libs/local_fastnda/version.py +0 -0
  306. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/log.py +0 -0
  307. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/logging.json +0 -0
  308. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/parameters/.cellpy_prms_default.conf +0 -0
  309. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/parameters/__init__.py +0 -0
  310. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/parameters/cell_schema.py +0 -0
  311. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/parameters/internal_settings.py +0 -0
  312. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/parameters/legacy/__init__.py +0 -0
  313. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/parameters/legacy/update_headers.py +0 -0
  314. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/parameters/prmreader.py +0 -0
  315. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/parameters/prms.py +0 -0
  316. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/__init__.py +0 -0
  317. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/backends/__init__.py +0 -0
  318. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/backends/base.py +0 -0
  319. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/batch_summary.py +0 -0
  320. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/context.py +0 -0
  321. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/cycle_legend.py +0 -0
  322. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/figures.py +0 -0
  323. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/headers.py +0 -0
  324. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/labels.py +0 -0
  325. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/prepare/__init__.py +0 -0
  326. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/prepare/curves.py +0 -0
  327. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/prepare/ica.py +0 -0
  328. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/prepare/raw.py +0 -0
  329. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/prepare/steps.py +0 -0
  330. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/prepare/summary.py +0 -0
  331. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/registry.py +0 -0
  332. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/spec.py +0 -0
  333. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/plotting/theme.py +0 -0
  334. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/__init__.py +0 -0
  335. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/capacity_curves.py +0 -0
  336. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/__init__.py +0 -0
  337. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/atomic.py +0 -0
  338. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/dtype.py +0 -0
  339. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/fids.py +0 -0
  340. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/format.py +0 -0
  341. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/keys.py +0 -0
  342. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/legacy_read.py +0 -0
  343. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/meta.py +0 -0
  344. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/meta_archive.py +0 -0
  345. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/read.py +0 -0
  346. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/selectors.py +0 -0
  347. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/translate.py +0 -0
  348. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/v9.py +0 -0
  349. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellpy_file/write.py +0 -0
  350. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/cellreader.py +0 -0
  351. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/data_structures.py +0 -0
  352. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/dbreader.py +0 -0
  353. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/do.py +0 -0
  354. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/filefinder.py +0 -0
  355. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/SQL Table IDs.txt +0 -0
  356. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/__init__.py +0 -0
  357. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/_aux_map.py +0 -0
  358. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/arbin_res.py +0 -0
  359. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/arbin_sql.py +0 -0
  360. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/arbin_sql_7.py +0 -0
  361. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/arbin_sql_config.py +0 -0
  362. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/arbin_sql_csv.py +0 -0
  363. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/arbin_sql_h5.py +0 -0
  364. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/arbin_sql_xlsx.py +0 -0
  365. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/base.py +0 -0
  366. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/batmo_bdf.py +0 -0
  367. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/biologics_mpr.py +0 -0
  368. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/configurations/__init__.py +0 -0
  369. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/configurations/batmo_bdf_bdf.py +0 -0
  370. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/configurations/maccor_txt_one.py +0 -0
  371. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/configurations/maccor_txt_three.py +0 -0
  372. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/configurations/maccor_txt_two.py +0 -0
  373. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/configurations/maccor_txt_zero.py +0 -0
  374. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/configurations/neware_txt_one.py +0 -0
  375. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/configurations/neware_txt_two.py +0 -0
  376. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/configurations/neware_txt_zero.py +0 -0
  377. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/contract.py +0 -0
  378. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/custom.py +0 -0
  379. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/declarations.py +0 -0
  380. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/ext_nda_reader.py +0 -0
  381. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/harmonize.py +0 -0
  382. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/hooks.py +0 -0
  383. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/loader_specific_modules/__init__.py +0 -0
  384. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/loader_specific_modules/biologic_file_format.py +0 -0
  385. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/local_instrument.py +0 -0
  386. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/maccor_txt.py +0 -0
  387. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/maccor_txt_native.py +0 -0
  388. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/neware_nda.py +0 -0
  389. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/neware_txt.py +0 -0
  390. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/neware_xlsx.py +0 -0
  391. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/pec_csv.py +0 -0
  392. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/processors/__init__.py +0 -0
  393. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/processors/post_processors.py +0 -0
  394. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/processors/pre_processors.py +0 -0
  395. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/registry.py +0 -0
  396. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/instruments/testing.py +0 -0
  397. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/journal_layer.py +0 -0
  398. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/json_dbreader.py +0 -0
  399. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/merger.py +0 -0
  400. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/meta_resolver.py +0 -0
  401. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/native_core.py +0 -0
  402. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/provenance.py +0 -0
  403. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/slicing.py +0 -0
  404. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/sql_dbreader.py +0 -0
  405. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/readers/test_meta.py +0 -0
  406. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/units.py +0 -0
  407. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/utils/__init__.py +0 -0
  408. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/utils/batch.py +0 -0
  409. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/utils/collectors.py +0 -0
  410. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/utils/diagnostics.py +0 -0
  411. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/utils/example_data.py +0 -0
  412. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/utils/helpers.py +0 -0
  413. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/utils/ica.py +0 -0
  414. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/utils/live.py +0 -0
  415. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/utils/ocv_rlx.py +0 -0
  416. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/utils/plotutils.py +0 -0
  417. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/utils/processor.py +0 -0
  418. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/cellpy/utils/template_registry.py +0 -0
  419. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/backfill_notebook_plotly_pngs.py +0 -0
  420. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/conda-recipes/README.md +0 -0
  421. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/conda-recipes/cellpy/meta.yaml +0 -0
  422. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/conda-recipes/cellpycore/meta.yaml +0 -0
  423. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/make_bad_fixtures.py +0 -0
  424. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/plot_preview_common.py +0 -0
  425. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/preview_curve_plots.py +0 -0
  426. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/preview_ica_plots.py +0 -0
  427. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/preview_plots.py +0 -0
  428. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/preview_summary_plots.py +0 -0
  429. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/regenerate_goldens.py +0 -0
  430. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/render_example_notebooks.py +0 -0
  431. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/snapshot_cli_surface.py +0 -0
  432. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/dev/snapshot_figure_specs.py +0 -0
  433. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/docker/Dockerfile.build-test +0 -0
  434. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/docker/sftp-test/README.md +0 -0
  435. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/docker/sftp-test/compose.yml +0 -0
  436. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/docker/sftp-test/data/hello.txt +0 -0
  437. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/docker/sftp-test/data/nested/sample.txt +0 -0
  438. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/environment.yml +0 -0
  439. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/environment_dev.yml +0 -0
  440. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/github_actions_environment.yml +0 -0
  441. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/noxfile.py +0 -0
  442. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/paper/.github/workflows/draft-pdf.yml +0 -0
  443. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/paper/.gitignore +0 -0
  444. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/paper/Figures/Cellpy-Utils.jpg +0 -0
  445. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/paper/Figures/CellpyCell.jpg +0 -0
  446. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/paper/Figures/CellpyData.jpg +0 -0
  447. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/paper/paper.bib +0 -0
  448. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/paper/paper.md +0 -0
  449. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/pyproject.toml +0 -0
  450. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/scripts/build_test.sh +0 -0
  451. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/scripts/dev_sync.sh +0 -0
  452. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/uv.lock +0 -0
  453. {cellpy-2.1.2a3 → cellpy-2.1.2a4}/zensical.toml +0 -0
@@ -0,0 +1,45 @@
1
+ # Issue #862: dva_plot(direction='both') does not distinguish the half-cycles visually (ica_plotter does)
2
+
3
+ Source: https://github.com/jepegit/cellpy/issues/862
4
+
5
+ ## Original issue text
6
+
7
+ **cellpy version:** 2.1.2a3
8
+
9
+ ## Summary
10
+
11
+ `ica_plotter` gained a visual distinction for `direction="both"` in #821 — the charge lobe is dashed (`line_dash`), so the two half-cycles are separable at a glance. `dva_plot(direction="both")` overlays both half-cycles too, but draws them **identically**: same colour, same trace name, no dash.
12
+
13
+ Only the hover tells them apart. On a static export (PNG/SVG/PDF for a report) that information is gone entirely.
14
+
15
+ ## Reproduction
16
+
17
+ ```python
18
+ import json, plotly.io as pio
19
+ from cellpy.utils.plotutils import dva_plot
20
+ from cellpy.utils import example_data
21
+
22
+ cell = example_data.cellpy_file()
23
+ fig = json.loads(pio.to_json(dva_plot(cell, cycles=[1], direction="both", backend="plotly")))
24
+ for t in fig["data"]:
25
+ print(t["name"], t["line"], t.get("showlegend"))
26
+ ```
27
+
28
+ ```
29
+ 1 {'color': 'rgb(68, 1, 84)', 'width': 1.5} True
30
+ 1 {'color': 'rgb(68, 1, 84)', 'width': 1.5} False
31
+ ```
32
+
33
+ Both traces: same `name`, same `legendgroup`, same colour, `dash` unset. Compare `ica_plotter(..., direction="both")`, which yields `1, charge` / `1, discharge` with `dash='dot'` on one of them.
34
+
35
+ The hover *is* correct — `customdata[1]` carries `charge`/`discharge` and the template shows it — so this is purely about the visual encoding.
36
+
37
+ ## Why it matters for apps
38
+
39
+ We're adding a DVA view to [cellpy-simple-gui](https://github.com/cellpy/cellpy-simple-gui) next to the existing ICA view. Same "Both" control, same user expectation, but two different behaviours: ICA is readable, DVA looks like a single doubled-back curve. We'll dash the discharge half app-side for now, which is exactly the kind of divergence #821 removed for ICA.
40
+
41
+ ## Suggested fix
42
+
43
+ Apply the #821 treatment in `dva_plot`: `line_dash` per direction (and ideally `"<cycle>, charge"` / `"<cycle>, discharge"` names, matching `ica_plotter`), so the two families stay consistent with each other.
44
+
45
+ Happy to send a PR if you'd like.
@@ -0,0 +1,90 @@
1
+ # Plan — Issue #862: dva_plot(direction='both') does not distinguish half-cycles visually
2
+
3
+ ## Goal
4
+
5
+ Make charge vs discharge half-cycles visually distinguishable (not just via hover) when `direction="both"` in `dva_plot` — and, since it's the same code path, in `ica_plot` too.
6
+
7
+ ## Investigation note (corrects the issue's framing)
8
+
9
+ `ica_plot` and `dva_plot` (`cellpy/utils/plotutils.py`) both route through the same shared
10
+ `prepare` (`cellpy/plotting/prepare/ica.py`) → `_render_ica_dva` renderer (one method per
11
+ backend: [`PlotlyBackend._render_ica_dva`](cellpy/plotting/backends/plotly.py) and
12
+ [`MatplotlibBackend._render_ica_dva`](cellpy/plotting/backends/mpl.py)). Reproduced with the
13
+ example cell: **`ica_plot(direction="both")` currently has the identical bug** — both docstrings
14
+ say outright "Line style is shared across charge and discharge." The issue's comparison is to
15
+ `cellpy.plotting.collected.ica_plotter` (the separate `Collection.plot` family-kind path fixed
16
+ in #821, `line_dash=direction_col` via `px.line`), not to `plotutils.ica_plot`.
17
+
18
+ Net effect: this is a **one-shared-fix** — patching `_render_ica_dva` fixes both `ica_plot` and
19
+ `dva_plot` at once, and they stay consistent with each other by construction (no per-kind
20
+ special-casing needed).
21
+
22
+ ## Constraints
23
+
24
+ - Keep the fix minimal: line style only (dash), not a legend/trace-naming overhaul. The issue's
25
+ "ideally `<cycle>, charge` / `<cycle>, discharge` names" is explicitly a nice-to-have
26
+ ("ideally"), and both backends currently key their legend/colorbar by **cycle** (color), grouped
27
+ across directions — renaming would double legend entries per cycle. Out of scope here.
28
+ - Match the #821 convention already established in `collected.py` for consistency across the
29
+ codebase: charge = solid, discharge = dotted (`px.line`'s default dash sequence gives the first
30
+ category `"solid"`, second `"dot"`, and `"charge"` < `"discharge"` alphabetically).
31
+ - Both backends (plotly + matplotlib) must get the fix — the issue only mentions plotly exports,
32
+ but the mpl backend has the identical "shared line style" bug and docstring.
33
+ - Do not change trace/line count, names, or hover content — `tests/data/figure_specs.json`
34
+ (structural snapshot, #567) does not record line style, so no golden-file update is needed as
35
+ long as trace count/names/axes are untouched.
36
+
37
+ ### Prior art
38
+
39
+ - `cellpy/plotting/collected.py::sequence_plotter` (#821 fix, lines ~573-580): sets
40
+ `plotly_arguments["line_dash"] = direction_col` when `direction == "both"`, for the *separate*
41
+ `Collection.plot(family_kind="ica")` path. Same convention (dash keyed by the `direction`
42
+ column values `"charge"` / `"discharge"` from `cellpy.ica.CHARGE` / `cellpy.ica.DISCHARGE`) is
43
+ reused here, but applied manually (since `_render_ica_dva` builds `go.Scatter` traces directly,
44
+ not through `px.line`).
45
+ - `tests/test_collected_ica_direction.py::test_ica_line_direction_both_overlays_without_coerce` —
46
+ existing pattern for asserting `{tr.line.dash for tr in fig.data}` has ≥2 distinct values;
47
+ mirror this style for the new plotutils-level test.
48
+
49
+ ## Approach
50
+
51
+ 1. **Plotly backend** (`cellpy/plotting/backends/plotly.py::PlotlyBackend._render_ica_dva`):
52
+ in the `for (cycle, direction), group in frame.groupby(group_cols, ...)` loop, compute
53
+ `dash = "dot" if direction == DISCHARGE else "solid"` and pass `dash=dash` into the existing
54
+ `line=dict(color=color, width=1.5)` dict. Import `CHARGE, DISCHARGE` from `cellpy.ica`
55
+ (`ICA_COLS` is already imported there).
56
+ 2. **Matplotlib backend** (`cellpy/plotting/backends/mpl.py::MatplotlibBackend._render_ica_dva`):
57
+ in the `for (cycle, _direction), group in frame.groupby(...)` loop, rename `_direction` to
58
+ `direction`, compute `linestyle = ":" if direction == DISCHARGE else "-"`, pass
59
+ `linestyle=linestyle` to `ax.plot(...)`.
60
+ 3. **Docstrings** — update both `_render_ica_dva` docstrings' "Line style is shared across charge
61
+ and discharge" line to describe the new dash/linestyle behaviour.
62
+ 4. **Tests** — add to `tests/test_ica_plot_prepare.py`:
63
+ - `test_ica_plot_both_direction_dash_differs` (and `dva_plot` equivalent, or parametrized over
64
+ both) for the plotly backend: call `ica_plot`/`dva_plot(direction="both", backend="plotly")`,
65
+ assert `{tr.line.dash for tr in fig.data}` has at least 2 distinct values.
66
+ - matplotlib equivalent: assert `{line.get_linestyle() for line in fig.get_axes()[0].get_lines()}`
67
+ has at least 2 distinct values for `direction="both"`.
68
+ - A `direction="charge"` (single-direction) sanity check that dash stays `"solid"`/`"-"` for
69
+ both kinds, guarding against a future regression that always-dashes regardless of direction.
70
+
71
+ ## Files to touch
72
+
73
+ - `cellpy/plotting/backends/plotly.py` — `PlotlyBackend._render_ica_dva`: add per-direction dash.
74
+ - `cellpy/plotting/backends/mpl.py` — `MatplotlibBackend._render_ica_dva`: add per-direction linestyle.
75
+ - `tests/test_ica_plot_prepare.py` — new direction/dash tests.
76
+ - `HISTORY.md` (at `/iflow-close`, per project convention) — patch-level fix note.
77
+
78
+ ## Test strategy
79
+
80
+ - `uv run pytest tests/test_ica_plot_prepare.py -m essential` for the fast path; then the
81
+ documented merge gate `uv run pytest -m essential` (per `AGENTS.md`).
82
+ - Plotting tests run fine outside `MPLBACKEND=Agg` requirement here since this repo's local dev
83
+ loop uses conda per project rules — will run via the activated `cellpy_dev_313` env (or `uv run`
84
+ if conda isn't needed locally); confirm whichever is available in the close step actually runs.
85
+ - Manually re-run the issue's repro snippet for both `ica_plot` and `dva_plot` to confirm dash
86
+ values differ and match before/after.
87
+
88
+ ## Open questions
89
+
90
+ None — scope, convention (match #821), and file list are all resolved from the codebase itself.
@@ -0,0 +1,28 @@
1
+ # Status — Issue #862
2
+
3
+ - [x] Done
4
+
5
+ ## What's done
6
+
7
+ - Investigated and confirmed `ica_plot` and `dva_plot` share the same `_render_ica_dva`
8
+ renderer (plotly + mpl) and both currently lacked dash distinction for `direction="both"`
9
+ (the issue's "ica_plotter already does this" comparison was to the separate
10
+ `cellpy.plotting.collected.ica_plotter`, fixed in #821 — a different code path).
11
+ - Plan written (`issue862_plan.md`), accepted.
12
+ - `PlotlyBackend._render_ica_dva` (`cellpy/plotting/backends/plotly.py`): dash keyed by
13
+ direction (`charge` solid, `discharge` dotted) whenever both directions are overlaid in the
14
+ frame; single-direction plots stay solid.
15
+ - `MatplotlibBackend._render_ica_dva` (`cellpy/plotting/backends/mpl.py`): same behaviour via
16
+ `linestyle` (`"-"` / `":"`).
17
+ - Docstrings updated on both renderers.
18
+ - New tests in `tests/test_ica_plot_prepare.py`: dash/linestyle differ for `direction="both"`
19
+ (both `ica_plot` and `dva_plot`, both backends), and stays solid for a single direction.
20
+ - `uv run pytest tests/test_ica_plot_prepare.py`, related plotting tests (49 passed), and the
21
+ full `uv run pytest -m essential` merge gate (698 passed, 1 skipped, 2 xfailed, 1 xpassed, no
22
+ regressions) all green with `MPLBACKEND=Agg`.
23
+ - `black --diff` / `flake8` on touched files: only pre-existing, unrelated findings (line-length
24
+ config mismatch); no new issues from this change.
25
+
26
+ ## Remaining work
27
+
28
+ None.
@@ -0,0 +1,35 @@
1
+ # Issue #863: No collect_dva: DVA is single-cell only, unlike summaries/cycles/ICA
2
+
3
+ Source: https://github.com/jepegit/cellpy/issues/863
4
+
5
+ ## Original issue text
6
+
7
+ **cellpy version:** 2.1.2a3
8
+
9
+ ## Summary
10
+
11
+ `cellpy.collect` exposes `collect_summaries`, `collect_cycles` and `collect_ica`, each returning a `Collection` that spans a batch of cells and plots through the collected path. **DVA has no equivalent** — `dva_plot(cell, ...)` takes a single cell, so differential voltage is the one analysis family that cannot be compared across cells.
12
+
13
+ ```python
14
+ >>> import cellpy.collect as C
15
+ >>> [hasattr(C, f"collect_{k}") for k in ("summaries", "cycles", "ica", "dva")]
16
+ [True, True, True, False]
17
+ ```
18
+
19
+ The `dva` plot family *is* registered (`registry.get("dva")` → `extras={'entry_point': 'dva_plot', 'kind': 'dva'}`), which makes the gap easy to trip over: the family shows up in the registry alongside `ica`, but there is no collector behind it.
20
+
21
+ ## Why it matters for apps
22
+
23
+ We just added a DVA view to [cellpy-simple-gui](https://github.com/cellpy/cellpy-simple-gui) next to the existing ICA view. ICA gets the full collected treatment — multiple cells, grouping, group-averaging, the whole `Collection` API. DVA had to be wired as a one-cell-at-a-time special case straight onto `dva_plot`, which means:
24
+
25
+ - no multi-cell DVA comparison, though that is exactly what you want when screening electrode formulations;
26
+ - a second code path in the app, with its own export (`dva_plot(return_data=True)` returns pandas, while collections are polars);
27
+ - the two sibling views behave differently for no reason the user can see.
28
+
29
+ `ica.dvdq` already produces the tidy per-cell frame (`cycle`, `direction`, `capacity`, `voltage`, `dvdq`), so the missing piece looks like the collector wrapper rather than the analysis.
30
+
31
+ ## Wish
32
+
33
+ A `collect_dva(batch, options=IcaOptions(...))` returning a `Collection` the same way `collect_ica` does — same `Collection.plot()` entry, same grouping/spread behaviour, same polars frame for export. That would let apps treat ICA and DVA as the two halves of one feature instead of two unrelated ones.
34
+
35
+ Happy to help if useful.
@@ -0,0 +1,103 @@
1
+ # Plan — Issue #863: No collect_dva (DVA is single-cell only)
2
+
3
+ ## Goal
4
+
5
+ Add `cellpy.collect.collect_dva(batch, options=IcaOptions(...))` returning a `Collection`,
6
+ mirroring `collect_ica`, so DVA gets the same multi-cell `Collection.plot()` / grouping /
7
+ save / export treatment as summaries/cycles/ICA.
8
+
9
+ ## Constraints
10
+
11
+ - Reuse the existing `cellpy.collect.options.IcaOptions` dataclass for both ICA and DVA (per
12
+ the issue's own proposed signature) rather than inventing a `DvaOptions` — add the one field
13
+ DVA actually needs (`capacity_resolution`) instead of a parallel dataclass.
14
+ - Match `collect_ica`'s per-cell cycle-isolation behaviour exactly (cycles resolved from the
15
+ *originally requested* set every iteration — the legacy cross-cell narrowing bug,
16
+ collectors.py:1691 — must not regress for DVA either).
17
+ - `Collection.plot()` must work out of the box for a DVA collection (`kind="dva"`) — currently
18
+ `Collection._FAMILY` has no `"dva"` entry (falls back to `"cycles"`, wrong columns) and
19
+ `render_collected` has no `family_kind == "dva"` branch (falls through to raw
20
+ `sequence_plotter` without ICA/DVA column defaults). Both must be wired, or `collect_dva(...).plot()`
21
+ breaks immediately — this is the same gap the issue calls out for the *plot family registry*
22
+ (`registry.get("dva")` already exists) vs the *collector*.
23
+ - Correct resolution knob: `cellpy.ica.dqdv` differentiates along **voltage** (needs `voltage_resolution`
24
+ for the q(V) interpolation); `cellpy.ica.dvdq` differentiates along **capacity** (needs
25
+ `capacity_resolution` for the V(q) interpolation, per `cellpy.ica.IcaOptions` docstring +
26
+ `dvdq`'s own docstring: "differentiates the smoothed V(q) curve"). `collect_ica` forwards
27
+ `voltage_resolution`; `collect_dva` must forward `capacity_resolution`, not `voltage_resolution`.
28
+ - Follow the existing one-file-per-collect-family convention (`cells.py`, `curves.py`, `ica.py`,
29
+ `summary.py`) — new `cellpy/collect/dva.py`, not a growing `ica.py`.
30
+ - Keep the legacy `BatchCollector` convenience-wrapper parity too (`ica_collector` exists
31
+ alongside `collect_ica`) — add `dva_collector` for symmetry; it is a 5-line wrapper.
32
+
33
+ ### Prior art
34
+
35
+ - `cellpy/collect/ica.py::collect_ica` — the function to mirror almost line-for-line: per-cell
36
+ `iter_cells` loop, per-cell cycle isolation via the *originally requested* tuple, `_as_polars`
37
+ conversion, `pl.concat(..., how="diagonal_relaxed")`, `opts.transforms` post-hooks,
38
+ `CollectionMeta(kind=..., options={...}, cells_included=...)`.
39
+ - `cellpy/plotting/collected.py::ica_plotter` (wraps `_cycles_plotter` with
40
+ `x="voltage", y="dqdv", z="cycle", g="cell"`) — mirror as `dva_plotter` with
41
+ `x="capacity", y="dvdq"` (labels/units swapped: "Capacity"/"mAh/g" and "dV/dQ"/"V/(mAh/g)").
42
+ `_cycles_plotter` / `sequence_plotter` are already column-name-generic — no changes needed there.
43
+ - `cellpy/collect/collection.py::Collection._FAMILY` and
44
+ `cellpy/plotting/collected.py::render_collected` — both need a `"dva"` branch/entry (see
45
+ Constraints above).
46
+ - `cellpy/collect/collector.py::ica_collector` — mirror as `dva_collector`.
47
+ - `tests/test_collectors.py::test_ica_collector_uses_the_specced_frame` /
48
+ `test_ica_collector_film_mode` / `test_ica_collector_fig_pr_cycle` — mirror for DVA in a new
49
+ `tests/test_collect_dva.py` (or add alongside in `test_collectors.py`; matches existing
50
+ `populated_batch` fixture reuse pattern).
51
+
52
+ ## Approach
53
+
54
+ 1. `cellpy/collect/options.py::IcaOptions` — add `capacity_resolution: float | None = None`
55
+ field (alongside existing `cycles`, `voltage_resolution`, `transforms`).
56
+ 2. New `cellpy/collect/dva.py::collect_dva(batch, options=None, **overrides) -> Collection`:
57
+ copy `collect_ica`'s structure, swap `ica.dqdv` → `ica.dvdq`, forward
58
+ `opts.capacity_resolution` (not `voltage_resolution`) into the per-cell call, `kind="dva"`,
59
+ `name=f"{batch.journal.name or 'batch'}_dva"`, `meta.options={"cycles": ..., "capacity_resolution": ...}`.
60
+ 3. `cellpy/collect/collector.py` — add `dva_collector(batch, options=None, *, autorun=True, **overrides)`
61
+ convenience wrapper bound to `collect_dva` (mirrors `ica_collector`).
62
+ 4. `cellpy/collect/__init__.py` — import/export `collect_dva`, `dva_collector`.
63
+ 5. `cellpy/collect/collection.py::Collection._FAMILY` — add `"dva": "dva"`.
64
+ 6. `cellpy/plotting/collected.py`:
65
+ - Add `dva_plotter(collected_curves, cycles_to_plot=None, backend="plotly", method="fig_pr_cell", direction="charge", **kwargs)`
66
+ mirroring `ica_plotter`, calling `_cycles_plotter(..., x="capacity", y="dvdq", z="cycle", g="cell", x_label="Capacity", x_unit="mAh/g", y_label="dV/dQ", y_unit="V/(mAh/g)", default_title="Differential Voltage Analysis Plots", ...)`.
67
+ - `render_collected`: add `if family_kind == "dva": return dva_plotter(frame, backend=backend, method=method, **opts)`.
68
+ - Update `collected_plot`'s docstring `family_kind` line to list `"dva"` too.
69
+ 7. **Tests** — new `tests/test_collect_dva.py` (reusing `populated_batch` from `tests/test_batch.py`,
70
+ same `pytest.importorskip("plotly")` guard as `test_collectors.py`):
71
+ - `collect_dva` produces the specced frame (`cycle`, `direction`, `capacity`, `voltage`, `dvdq`)
72
+ and `.plot()` renders a non-empty figure.
73
+ - `dva_collector` convenience wrapper runs end to end (mirrors `test_ica_collector_uses_the_specced_frame`).
74
+ - `capacity_resolution` reaches `ica.dvdq` (monkeypatch spy, mirrors
75
+ `test_collect_cycles_forwards_mode_and_method`), and that `voltage_resolution` is
76
+ **not** what gets forwarded (guards the resolution-knob mixup called out above).
77
+ - `Collection(kind="dva").plot()` picks the `dva` family (not the `cycles` fallback) —
78
+ regression guard for the `_FAMILY` wiring.
79
+
80
+ ## Files to touch
81
+
82
+ - `cellpy/collect/options.py` — add `capacity_resolution` to `IcaOptions`.
83
+ - `cellpy/collect/dva.py` — new, `collect_dva`.
84
+ - `cellpy/collect/collector.py` — add `dva_collector`.
85
+ - `cellpy/collect/__init__.py` — export both.
86
+ - `cellpy/collect/collection.py` — `_FAMILY` entry.
87
+ - `cellpy/plotting/collected.py` — `dva_plotter` + `render_collected` branch + docstring.
88
+ - `tests/test_collect_dva.py` — new.
89
+ - `HISTORY.md` (at `/iflow-close`).
90
+
91
+ ## Test strategy
92
+
93
+ - `uv run pytest tests/test_collect_dva.py tests/test_collectors.py -v` (needs plotting extras;
94
+ both files already guard with `pytest.importorskip("plotly")`).
95
+ - `MPLBACKEND=Agg uv run pytest -m essential` merge gate.
96
+ - Mark new tests `@pytest.mark.essential` matching the existing collector test conventions (none
97
+ of `test_collectors.py`'s existing tests carry the marker today — check current state at build
98
+ time and follow whatever the file does, per the essential-tests-review step in `/iflow-close`).
99
+
100
+ ## Open questions
101
+
102
+ None — the API shape, options reuse, and the two wiring gaps (`_FAMILY`, `render_collected`)
103
+ were all resolved by reading the existing ICA collector/plotter pair end to end.
@@ -0,0 +1,33 @@
1
+ # Status — Issue #863
2
+
3
+ - [x] Done
4
+
5
+ ## What's done
6
+
7
+ - Investigated `collect_ica` / `ica_plotter` / `Collection._FAMILY` / `render_collected` end to
8
+ end to establish the mirror pattern for DVA.
9
+ - Identified the resolution-knob subtlety: `dqdv` uses `voltage_resolution`, `dvdq` uses
10
+ `capacity_resolution`.
11
+ - Plan written (`issue863_plan.md`), accepted.
12
+ - `cellpy/collect/options.py::IcaOptions` — added `capacity_resolution` field (shared by ICA
13
+ and DVA, each forwarding only its own knob).
14
+ - New `cellpy/collect/dva.py::collect_dva` — mirrors `collect_ica`, per-cell cycle isolation,
15
+ `kind="dva"`, forwards `capacity_resolution` to `ica.dvdq`.
16
+ - `cellpy/collect/collector.py::dva_collector` convenience wrapper.
17
+ - Exported `collect_dva` / `dva_collector` from `cellpy/collect/__init__.py`.
18
+ - `cellpy/collect/collection.py::Collection._FAMILY["dva"] = "dva"`.
19
+ - `cellpy/plotting/collected.py`: new `dva_plotter` (mirrors `ica_plotter`, x=capacity/y=dvdq),
20
+ wired into `render_collected`'s `family_kind == "dva"` branch, docstring updated.
21
+ - New `tests/test_collect_dva.py` (5 tests): specced frame, `Collection.kind`, resolution-knob
22
+ regression guard (`capacity_resolution` reaches `dvdq`, not `voltage_resolution`), `_FAMILY`
23
+ wiring regression guard, `fig_pr_cycle` layout.
24
+ - `uv run pytest tests/test_collect_dva.py` (5 passed), related collect/ICA/plotting tests
25
+ (70 passed), and the full `uv run pytest -m essential` merge gate (703 passed, 1 skipped,
26
+ 2 xfailed, 1 xpassed — no regressions) all green with `MPLBACKEND=Agg`.
27
+ - `black --diff` / `flake8` on touched/new files: only pre-existing, unrelated findings
28
+ (line-length config mismatch; fixture-shadowing F811 identical to `test_collectors.py`;
29
+ pre-existing unused `field` import in `options.py`); nothing new from this change.
30
+
31
+ ## Remaining work
32
+
33
+ None.
@@ -47,6 +47,14 @@ current issue**. `/iflow-doctor` may audit the whole suite against this table.
47
47
  | tests/test_cli_light_import.py::test_setup_deps_probes_optional_modules | yes | yes | cli_api.setup_config --deps | #839 | opt-in optional probe |
48
48
  | tests/test_cellpy_file_v9.py::test_failed_resave_keeps_the_old_file | yes | yes | cellpy_file.atomic.atomic_write / v9.save / CellpyCell.save | #845 | data-loss guard: interrupted re-save must not destroy the old file |
49
49
  | tests/test_cellpy_file_v9.py::test_failed_first_save_leaves_no_file | yes | yes | cellpy_file.atomic.atomic_write / v9.save | #845 | no half-written archive on a fresh path |
50
+ | tests/test_ica_plot_prepare.py::test_ica_dva_plotly_both_direction_dash_differs | yes | yes | plotting.backends.plotly._render_ica_dva | #862 | charge solid / discharge dot |
51
+ | tests/test_ica_plot_prepare.py::test_ica_dva_plotly_single_direction_stays_solid | yes | yes | plotting.backends.plotly._render_ica_dva | #862 | single direction stays solid |
52
+ | tests/test_ica_plot_prepare.py::test_ica_dva_matplotlib_both_direction_linestyle_differs | yes | yes | plotting.backends.mpl._render_ica_dva | #862 | "-" / ":" linestyle |
53
+ | tests/test_collect_dva.py::test_dva_collector_uses_the_specced_frame | yes | yes | collect.dva.collect_dva | #863 | specced frame cols |
54
+ | tests/test_collect_dva.py::test_collect_dva_returns_a_dva_collection | yes | yes | collect.dva.collect_dva | #863 | kind="dva" |
55
+ | tests/test_collect_dva.py::test_collect_dva_forwards_capacity_resolution_not_voltage_resolution | yes | yes | collect.dva.collect_dva / ica.dvdq | #863 | resolution-knob guard |
56
+ | tests/test_collect_dva.py::test_dva_collection_plot_uses_the_dva_family_not_cycles | yes | yes | collect.collection.Collection._FAMILY | #863 | family wiring guard |
57
+ | tests/test_collect_dva.py::test_dva_collector_fig_pr_cycle | yes | yes | plotting.collected.dva_plotter | #863 | per-cycle layout |
50
58
  | tests/test_cellpy_file_v9.py::test_incomplete_archive_is_rejected_before_replace | yes | yes | v9._verify_members | #845 | missing zip member never replaces a good file |
51
59
  | tests/test_cellpy_file_v9.py::test_failed_hdf5_resave_keeps_the_old_file | no | no | cellpy_file.write.save (v8/HDF5) | #845 | same guard for the legacy writer; unmarked to keep Tier 1 fast |
52
60
  | tests/test_config.py::test_active_config_file_prefers_toml | yes | yes | config.loader.active_config_file | #851 | "which config am I using" must stay honest |
@@ -17,6 +17,8 @@
17
17
  - Pretty-print cycles collector facet strips (Cycle N / cell label, not cycle_num=). (#820)
18
18
  - Honour share_y / match_axes on collected summary spread_plot. (#817)
19
19
  - ICA plotter: honour direction for line layouts; support direction='both'. (#821)
20
+ - ``ica_plot`` / ``dva_plot``: dash discharge (dotted) vs charge (solid) when ``direction='both'`` so the two half-cycles stay distinguishable on a static export. (#862)
21
+ - ``cellpy.collect.collect_dva``: multi-cell DVA collection (mirrors ``collect_ica``), returning a ``Collection`` with the same ``Collection.plot()`` / grouping / save entry points; ``dva_collector`` convenience wrapper. (#863)
20
22
 
21
23
  ## [2.1.1.post6] - 2026-08-02
22
24
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cellpy
3
- Version: 2.1.2a3
3
+ Version: 2.1.2a4
4
4
  Summary: Extract and manipulate data from battery data testers.
5
5
  Project-URL: Homepage, https://github.com/jepegit/cellpy
6
6
  Project-URL: Repository, https://github.com/jepegit/cellpy
@@ -22,12 +22,14 @@ from cellpy.collect.collection import Collection, CollectionMeta, load_collectio
22
22
  from cellpy.collect.collector import (
23
23
  BatchCollector,
24
24
  cycles_collector,
25
+ dva_collector,
25
26
  ica_collector,
26
27
  normalize_column,
27
28
  standard_gravimetric,
28
29
  summary_collector,
29
30
  )
30
31
  from cellpy.collect.curves import collect_cycles
32
+ from cellpy.collect.dva import collect_dva
31
33
  from cellpy.collect.ica import collect_ica
32
34
  from cellpy.collect.options import (
33
35
  CurveOptions,
@@ -44,6 +46,7 @@ __all__ = [
44
46
  "collect_summaries",
45
47
  "collect_cycles",
46
48
  "collect_ica",
49
+ "collect_dva",
47
50
  "from_cells",
48
51
  "iter_cells",
49
52
  "CellItem",
@@ -55,6 +58,7 @@ __all__ = [
55
58
  "summary_collector",
56
59
  "cycles_collector",
57
60
  "ica_collector",
61
+ "dva_collector",
58
62
  "standard_gravimetric",
59
63
  "normalize_column",
60
64
  ]
@@ -56,8 +56,8 @@ class Collection:
56
56
  name: str
57
57
  meta: CollectionMeta
58
58
 
59
- #: collection kind -> ``collected_plot`` family (#657).
60
- _FAMILY = {"summary": "summary", "cycles": "cycles", "ica": "ica"}
59
+ #: collection kind -> ``collected_plot`` family (#657, #863).
60
+ _FAMILY = {"summary": "summary", "cycles": "cycles", "ica": "ica", "dva": "dva"}
61
61
 
62
62
  @property
63
63
  def is_grouped(self) -> bool:
@@ -18,6 +18,7 @@ from typing import Any, Callable
18
18
  import polars as pl
19
19
 
20
20
  from cellpy.collect.curves import collect_cycles
21
+ from cellpy.collect.dva import collect_dva
21
22
  from cellpy.collect.ica import collect_ica
22
23
  from cellpy.collect.options import CurveOptions, IcaOptions, SummaryOptions
23
24
  from cellpy.collect.summary import collect_summaries
@@ -117,6 +118,13 @@ def ica_collector(
117
118
  return BatchCollector(batch, collect_ica, options, autorun=autorun, **overrides)
118
119
 
119
120
 
121
+ def dva_collector(
122
+ batch: Any, options: IcaOptions | None = None, *, autorun: bool = True, **overrides
123
+ ) -> BatchCollector:
124
+ """Convenience :class:`BatchCollector` bound to :func:`collect_dva`."""
125
+ return BatchCollector(batch, collect_dva, options, autorun=autorun, **overrides)
126
+
127
+
120
128
  def normalize_column(
121
129
  column: str, norm_factor: float, out: str | None = None
122
130
  ) -> Callable[[pl.DataFrame], pl.DataFrame]:
@@ -0,0 +1,95 @@
1
+ """dV/dQ (DVA) collection.
2
+
3
+ Per-cell dV/dQ curves via :func:`cellpy.ica.dvdq`, concatenated into one tidy
4
+ frame with ``cell`` / ``group`` / ``sub_group`` keys. Mirrors
5
+ :func:`cellpy.collect.ica.collect_ica` -- including the per-cell cycle
6
+ isolation that fixes the legacy cross-cell narrowing bug (collectors.py:1691)
7
+ -- but emits the specced DVA frame: ``cycle, direction, capacity, voltage,
8
+ dvdq`` (#863).
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from typing import Any
14
+
15
+ import polars as pl
16
+
17
+ from cellpy.collect.cells import iter_cells
18
+ from cellpy.collect.collection import Collection, CollectionMeta
19
+ from cellpy.collect.options import IcaOptions
20
+
21
+
22
+ def _as_polars(frame: Any) -> pl.DataFrame | None:
23
+ if frame is None:
24
+ return None
25
+ if isinstance(frame, pl.DataFrame):
26
+ return frame
27
+ try:
28
+ return pl.from_pandas(frame)
29
+ except (TypeError, ValueError):
30
+ return None
31
+
32
+
33
+ def collect_dva(
34
+ batch: Any, options: IcaOptions | None = None, **overrides
35
+ ) -> Collection:
36
+ """Collect dV/dQ (differential voltage) curves per cell into one Collection.
37
+
38
+ Cycle selection is derived per cell from the *originally requested* cycles
39
+ every iteration, so a cell missing a cycle never narrows the request for
40
+ the cells after it (mirrors :func:`cellpy.collect.collect_ica`).
41
+ """
42
+ from cellpy.utils import ica
43
+
44
+ opts = options or IcaOptions()
45
+ if overrides:
46
+ opts = opts.replace(**overrides)
47
+ requested = tuple(opts.cycles) if opts.cycles is not None else None
48
+
49
+ # dV/dQ differentiates along capacity (V(q) interpolation), unlike
50
+ # dQ/dV's voltage_resolution (q(V) interpolation).
51
+ dvdq_kwargs: dict[str, Any] = {}
52
+ if opts.capacity_resolution is not None:
53
+ dvdq_kwargs["capacity_resolution"] = opts.capacity_resolution
54
+
55
+ frames: list[pl.DataFrame] = []
56
+ for item in iter_cells(batch):
57
+ cell = item.cell
58
+ if requested is None:
59
+ cycles = None
60
+ else:
61
+ available = set(cell.get_cycle_numbers())
62
+ cycles = [c for c in requested if c in available]
63
+ if not cycles:
64
+ continue
65
+
66
+ curve = _as_polars(ica.dvdq(cell, cycles=cycles, **dvdq_kwargs))
67
+ if curve is None or curve.height == 0:
68
+ continue
69
+ frames.append(
70
+ curve.with_columns(
71
+ pl.lit(item.label).alias("cell"),
72
+ pl.lit(item.group).alias("group"),
73
+ pl.lit(item.sub_group).alias("sub_group"),
74
+ )
75
+ )
76
+
77
+ data = pl.concat(frames, how="diagonal_relaxed") if frames else pl.DataFrame()
78
+ for transform in opts.transforms:
79
+ data = transform(data)
80
+
81
+ meta = CollectionMeta(
82
+ kind="dva",
83
+ batch_name=batch.journal.name,
84
+ options={
85
+ "cycles": list(requested) if requested else None,
86
+ "capacity_resolution": opts.capacity_resolution,
87
+ },
88
+ cells_included=list(batch.cells),
89
+ )
90
+ return Collection(
91
+ data=data,
92
+ kind="dva",
93
+ name=f"{batch.journal.name or 'batch'}_dva",
94
+ meta=meta,
95
+ )
@@ -97,10 +97,19 @@ class CurveOptions:
97
97
 
98
98
  @dataclass(frozen=True)
99
99
  class IcaOptions:
100
- """Options for dQ/dV (ICA) collection."""
100
+ """Options for dQ/dV (ICA) and dV/dQ (DVA) collection.
101
+
102
+ Shared by :func:`cellpy.collect.collect_ica` and
103
+ :func:`cellpy.collect.collect_dva` -- each forwards only the resolution
104
+ knob its own transform actually uses: ``dqdv`` differentiates along
105
+ voltage (needs ``voltage_resolution`` for the q(V) interpolation);
106
+ ``dvdq`` differentiates along capacity (needs ``capacity_resolution`` for
107
+ the V(q) interpolation).
108
+ """
101
109
 
102
110
  cycles: tuple[int, ...] | None = None
103
111
  voltage_resolution: float | None = None
112
+ capacity_resolution: float | None = None
104
113
  transforms: tuple[Transform, ...] = ()
105
114
 
106
115
  def replace(self, **changes) -> "IcaOptions":