cellpycore 0.1.1__tar.gz → 0.1.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.
- cellpycore-0.1.2/.issueflows/03-solved-issues/issue44_status.md +23 -0
- cellpycore-0.1.2/.issueflows/03-solved-issues/issue45_original.md +17 -0
- cellpycore-0.1.2/.issueflows/03-solved-issues/issue45_plan.md +130 -0
- cellpycore-0.1.2/.issueflows/03-solved-issues/issue45_status.md +56 -0
- cellpycore-0.1.2/.issueflows/03-solved-issues/issue54_original.md +45 -0
- cellpycore-0.1.2/.issueflows/03-solved-issues/issue54_plan.md +53 -0
- cellpycore-0.1.2/.issueflows/03-solved-issues/issue54_status.md +19 -0
- cellpycore-0.1.2/.issueflows/03-solved-issues/issue55_original.md +47 -0
- cellpycore-0.1.2/.issueflows/03-solved-issues/issue55_plan.md +95 -0
- cellpycore-0.1.2/.issueflows/03-solved-issues/issue55_status.md +34 -0
- cellpycore-0.1.2/.issueflows/03-solved-issues/issue56_original.md +64 -0
- cellpycore-0.1.2/.issueflows/03-solved-issues/issue56_plan.md +48 -0
- cellpycore-0.1.2/.issueflows/03-solved-issues/issue56_status.md +26 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/04-designs-and-guides/cellpy-core-integration-roadmap.md +2 -1
- cellpycore-0.1.2/.issueflows/04-designs-and-guides/release-procedure.md +60 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/04-designs-and-guides/selector-dead-code-deferral.md +18 -0
- cellpycore-0.1.2/HISTORY.md +48 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/PKG-INFO +16 -2
- {cellpycore-0.1.1 → cellpycore-0.1.2}/README.md +15 -1
- {cellpycore-0.1.1 → cellpycore-0.1.2}/graphify-out/.graphify_labels.json +16 -3
- cellpycore-0.1.2/graphify-out/GRAPH_REPORT.md +329 -0
- cellpycore-0.1.2/graphify-out/graph.html +305 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/graphify-out/graph.json +7655 -4996
- {cellpycore-0.1.1 → cellpycore-0.1.2}/graphify-out/manifest.json +27 -23
- {cellpycore-0.1.1 → cellpycore-0.1.2}/pyproject.toml +1 -1
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/cell_core.py +124 -5
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/selectors.py +2 -180
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/summarizers.py +76 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/uv.lock +1 -1
- cellpycore-0.1.1/.issueflows/02-partly-solved-issues/issue44_status.md +0 -16
- cellpycore-0.1.1/HISTORY.md +0 -23
- cellpycore-0.1.1/graphify-out/GRAPH_REPORT.md +0 -291
- cellpycore-0.1.1/graphify-out/graph.html +0 -305
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.aliases +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/rules/cellpy-core-migration.mdc +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/rules/graphify.mdc +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/rules/issueflow-rules.mdc +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/rules/kiss.mdc +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/rules/this-project.mdc +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/caveman/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/grill-me/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-cleanup/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-close/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-comments/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-fix/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-graphify/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-history-update/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-init/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-pause/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-pick/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-plan/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-start/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-status/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-version-bump/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.cursor/skills/iflow-yolo/SKILL.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.gitignore +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/00-tools/.gitkeep +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/00-tools/README.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/01-current-issues/.gitkeep +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/02-partly-solved-issues/.gitkeep +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/.gitkeep +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue10_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue10_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue10_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue12_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue12_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue12_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue13_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue13_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue13_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue21_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue21_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue21_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue22_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue22_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue22_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue23_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue23_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue23_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue24_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue24_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue29_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue29_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue29_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue30_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue30_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue30_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue32_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue32_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue32_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue34_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue34_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue36_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue36_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue39_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue39_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue39_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue40_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue40_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue40_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue41_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue41_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue41_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue42_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue42_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue42_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue43_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue43_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue43_status.md +0 -0
- {cellpycore-0.1.1/.issueflows/02-partly-solved-issues → cellpycore-0.1.2/.issueflows/03-solved-issues}/issue44_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue50_original.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue50_plan.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/03-solved-issues/issue50_status.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/04-designs-and-guides/.gitkeep +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/04-designs-and-guides/cellpy-core-integration-into-cellpy.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/04-designs-and-guides/cellpy-core-migration.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/04-designs-and-guides/code-review-2026-07.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/04-designs-and-guides/column-headers-review.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/04-designs-and-guides/metadata-scaffolding.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/04-designs-and-guides/step-table-polars-migration.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/04-designs-and-guides/summary-extractors.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/04-designs-and-guides/test-data-and-fixtures.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/04-designs-and-guides/test-metadata-and-merging.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/04-designs-and-guides/this-project.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.issueflows/config.toml +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.python-version +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/.vscode/settings.json +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/AGENTS.md +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/LICENSE +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/cellpy-core.code-workspace +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/graphify-out/.graphify_root +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/scratch.db +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/__init__.py +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/_helpers.py +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/config.py +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/extractors.py +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/header_mapping.py +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/legacy.py +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/metadata/__init__.py +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/metadata/io.py +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/metadata/models.py +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/settings_base.py +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/timestamps.py +0 -0
- {cellpycore-0.1.1 → cellpycore-0.1.2}/src/cellpycore/units.py +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Issue #44 status — Release: tag cellpy-core (and decide PyPI publish)
|
|
2
|
+
|
|
3
|
+
- [x] Done
|
|
4
|
+
|
|
5
|
+
## What has been done
|
|
6
|
+
|
|
7
|
+
- User added `.github/workflows/release.yml`: on GitHub release publish → ruff + pytest → `uv build` → PyPI publish (trusted publishing via `pypi` environment, `id-token: write`).
|
|
8
|
+
- User added a release alias (commit `06831f0`) to trigger releases, modeled on jepegit/issue-flow.
|
|
9
|
+
- Release `v0.1.0` was published 2026-07-02, but its CI test job failed on ruff F401 — PyPI publish never ran. Fix landed via PR #53.
|
|
10
|
+
- **2026-07-02 (evening): release verified end-to-end.** `v0.1.1` tagged, `release.yml` ran green, and `cellpycore 0.1.1` is live on PyPI. The release/tagging convention works.
|
|
11
|
+
- Note: tag `v0.1.1` points at `63066bf`, which **pre-dates** the #45 selector removal (merged to `main` as `2da165e` after the tag). cellpy `master` is compatible with both (it no longer passes `selector=` and works against 0.1.1 and `main`). The next release will include the removal.
|
|
12
|
+
|
|
13
|
+
## Remaining work
|
|
14
|
+
|
|
15
|
+
- ~~Document the release procedure~~ — done 2026-07-02:
|
|
16
|
+
`.issueflows/04-designs-and-guides/release-procedure.md` (alias, workflow,
|
|
17
|
+
happy path, failure mode, per-release re-pin checklist).
|
|
18
|
+
- ~~Execute the cellpy-side re-pin~~ — done 2026-07-02: cellpy PR
|
|
19
|
+
[jepegit/cellpy#400](https://github.com/jepegit/cellpy/pull/400)
|
|
20
|
+
(branch `core44-pin-cellpycore-release`): `cellpycore>=0.1.1` from PyPI,
|
|
21
|
+
editable `[tool.uv.sources]` override kept, `allow-direct-references`
|
|
22
|
+
removed, `uv.lock` refreshed, seam tests green.
|
|
23
|
+
- ~~Merge PR #400~~ — merged 2026-07-02 17:21Z. **Issue fully resolved.**
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Issue #45: Cleanup (blocked): remove create_selector/summary_selector_exluder once cellpy migrates off them
|
|
2
|
+
|
|
3
|
+
Source: https://github.com/cellpy/cellpy-core/issues/45
|
|
4
|
+
|
|
5
|
+
## Original issue text
|
|
6
|
+
|
|
7
|
+
Tracking issue for the deferred dead-code removal documented in `.issueflows/04-designs-and-guides/selector-dead-code-deferral.md`.
|
|
8
|
+
|
|
9
|
+
## Status: blocked (do not remove yet)
|
|
10
|
+
|
|
11
|
+
`selectors.create_selector` is **still imported by the external cellpy repo** (`cellpy/readers/cellreader.py` via `core_selectors.create_selector(...)`, and `cellpy/tests/test_slim.py`). `selectors.summary_selector_exluder` is the pandas engine it wraps, so it must live as long as `create_selector` does. cellpy pins `cellpycore @ ...@main`, so removing now breaks cellpy at its next pin resolution.
|
|
12
|
+
|
|
13
|
+
## Removal trigger (future work)
|
|
14
|
+
|
|
15
|
+
Remove **both** functions only after cellpy stops importing `core_selectors.create_selector` (i.e. cellpy moves its summary selection onto the native `make_summary` path or its own helper). Then this is a small dead-code deletion in `src/cellpycore/selectors.py`.
|
|
16
|
+
|
|
17
|
+
(The sibling pair `generate_absolute_summary_columns` / `end_voltage_to_summary` was already removed in issue #24.)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Issue #45 plan: remove `create_selector` / `summary_selector_exluder` (two-repo cleanup)
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Migrate cellpy off `core_selectors.create_selector`, then delete both
|
|
6
|
+
`create_selector` and `summary_selector_exluder` from cellpy-core
|
|
7
|
+
(`src/cellpycore/selectors.py`), plus the dead `selector` parameter on
|
|
8
|
+
`make_core_summary`.
|
|
9
|
+
|
|
10
|
+
## Key finding (unblocks the issue)
|
|
11
|
+
|
|
12
|
+
Both `make_core_summary` implementations in `src/cellpycore/cell_core.py`
|
|
13
|
+
(native, line ~159; legacy bridge, line ~563) accept `selector` but **never use
|
|
14
|
+
it** — the polars engine selects cycle-end rows via `final_data_points`
|
|
15
|
+
internally. So the selector cellpy builds in `_make_summary`
|
|
16
|
+
(`cellpy/readers/cellreader.py:5794-5805`) and passes at line 5917 is already a
|
|
17
|
+
no-op, as are cellpy's public `selector` / `selector_type` / `exclude_types` /
|
|
18
|
+
`exclude_steps` kwargs on `make_summary`. Migration is therefore a pure
|
|
19
|
+
dead-code removal on the cellpy side too — no behavior replacement needed.
|
|
20
|
+
|
|
21
|
+
## Constraints
|
|
22
|
+
|
|
23
|
+
- **Merge order:** cellpy pins `cellpycore @ git+…@main`
|
|
24
|
+
(`cellpy/pyproject.toml:61`). The cellpy PR (stop importing) must merge
|
|
25
|
+
**before** the cellpy-core PR (delete functions), or cellpy breaks at its
|
|
26
|
+
next pin resolution.
|
|
27
|
+
- **Branch, don't fork** (per `cellpy-core-migration.md`): cellpy work goes on
|
|
28
|
+
a dedicated branch of the existing cellpy repo, e.g.
|
|
29
|
+
`core45-drop-create-selector`. cellpy-core work stays on the existing
|
|
30
|
+
branch `45-cleanup-blocked-remove-create_selectorsummary_selector_exluder-once-cellpy-migrates-off-them`.
|
|
31
|
+
- **Local dev wiring:** cellpy already has the editable
|
|
32
|
+
`[tool.uv.sources] cellpycore = { path = "../cellpy-core", editable = true }`
|
|
33
|
+
override, so both branches can be tested together locally.
|
|
34
|
+
- **User decisions (2026-07-02):** keep cellpy's `selector*` / `exclude*`
|
|
35
|
+
kwargs but emit `DeprecationWarning` when supplied; also remove the dead
|
|
36
|
+
`selector` parameter from both `make_core_summary` signatures in core.
|
|
37
|
+
|
|
38
|
+
### Prior art
|
|
39
|
+
|
|
40
|
+
- `selector-dead-code-deferral.md` (04-designs-and-guides) — the deferral
|
|
41
|
+
decision this issue executes; update it when done.
|
|
42
|
+
- `code-review-2026-07.md` — notes #45 covers only these two functions;
|
|
43
|
+
`get_step_numbers` / `get_cycle_numbers` / `get_rates` stay.
|
|
44
|
+
- Issue #24 removed the sibling pair `generate_absolute_summary_columns` /
|
|
45
|
+
`end_voltage_to_summary`; `tests/test_schema.py::test_no_module_header_globals`
|
|
46
|
+
shows the "assert name gone" test pattern to mirror.
|
|
47
|
+
- Toolbox (`.issueflows/00-tools/`) and graph checked: no relevant helper.
|
|
48
|
+
|
|
49
|
+
## Approach
|
|
50
|
+
|
|
51
|
+
### Phase 1 — cellpy (branch `core45-drop-create-selector`)
|
|
52
|
+
|
|
53
|
+
1. Create the branch from cellpy's default branch.
|
|
54
|
+
2. `cellpy/readers/cellreader.py`:
|
|
55
|
+
- Remove `from cellpycore import selectors as core_selectors` (line 73).
|
|
56
|
+
- In `_make_summary`: delete the selector-building block (lines 5794-5805)
|
|
57
|
+
and stop passing `selector=selector` to `self.core.make_core_summary`
|
|
58
|
+
(line 5917).
|
|
59
|
+
- Emit `DeprecationWarning` when `selector`, `selector_type`,
|
|
60
|
+
`exclude_types`, or `exclude_steps` is supplied (non-None) to
|
|
61
|
+
`make_summary` — they have been no-ops since the core seam.
|
|
62
|
+
3. `tests/test_slim.py`: drop the `core_selectors` import; update
|
|
63
|
+
`test_direct_core_make_core_summary` to call
|
|
64
|
+
`make_core_summary(data, find_ir=True, find_end_voltage=True)` without a
|
|
65
|
+
selector.
|
|
66
|
+
4. Run cellpy tests (conda `cellpy_dev_313`): at least `pytest tests/test_slim.py`
|
|
67
|
+
plus summary-related tests (`-k summary`).
|
|
68
|
+
|
|
69
|
+
### Phase 2 — cellpy-core (existing branch for #45)
|
|
70
|
+
|
|
71
|
+
1. `src/cellpycore/selectors.py`: delete `create_selector` and
|
|
72
|
+
`summary_selector_exluder`; remove now-unused imports/constants
|
|
73
|
+
(`functools`, `FIRST`/`LAST`/`DELTA` if unused elsewhere — verify).
|
|
74
|
+
2. `src/cellpycore/cell_core.py`: remove the unused `selector` parameter from
|
|
75
|
+
both `make_core_summary` signatures + docstrings.
|
|
76
|
+
3. `tests/test_schema.py`: extend the dead-code assertions with
|
|
77
|
+
`create_selector` / `summary_selector_exluder` gone from `selectors`
|
|
78
|
+
(mirror `test_no_module_header_globals`).
|
|
79
|
+
4. Docs: update `selector-dead-code-deferral.md` (resolved, date, link #45)
|
|
80
|
+
and flip #45 in `cellpy-core-integration-roadmap.md` from blocked to done.
|
|
81
|
+
5. Run `uv run pytest`; rerun cellpy's `test_slim.py` against the edited core
|
|
82
|
+
via the editable path source.
|
|
83
|
+
|
|
84
|
+
### Merge sequencing
|
|
85
|
+
|
|
86
|
+
cellpy PR merges first → then cellpy-core PR. Local editable wiring keeps both
|
|
87
|
+
testable during development.
|
|
88
|
+
|
|
89
|
+
## Files to touch
|
|
90
|
+
|
|
91
|
+
- `cellpy/cellpy/readers/cellreader.py` — remove import + selector block, add
|
|
92
|
+
deprecation warnings.
|
|
93
|
+
- `cellpy/tests/test_slim.py` — drop selector usage.
|
|
94
|
+
- `cellpy-core/src/cellpycore/selectors.py` — delete the two functions.
|
|
95
|
+
- `cellpy-core/src/cellpycore/cell_core.py` — drop dead `selector` param (2 sites).
|
|
96
|
+
- `cellpy-core/tests/test_schema.py` — add removed-name assertions.
|
|
97
|
+
- `cellpy-core/.issueflows/04-designs-and-guides/selector-dead-code-deferral.md`,
|
|
98
|
+
`cellpy-core-integration-roadmap.md` — status updates.
|
|
99
|
+
|
|
100
|
+
## Test strategy
|
|
101
|
+
|
|
102
|
+
- cellpy-core: `uv run pytest` (top dir) — includes `tests/test_golden.py`
|
|
103
|
+
(golden parquet fixtures: 103 steps / 18 cycles / cycle-1 `data_point` 1457),
|
|
104
|
+
which is the core-side parity oracle.
|
|
105
|
+
- cellpy: activate conda `cellpy_dev_313`, run `pytest tests/test_slim.py` and
|
|
106
|
+
`pytest -k summary`.
|
|
107
|
+
|
|
108
|
+
### End-to-end verification (both branches together, before either PR)
|
|
109
|
+
|
|
110
|
+
With the cellpy branch checked out and the editable
|
|
111
|
+
`[tool.uv.sources]` path resolving `cellpycore` to the edited
|
|
112
|
+
`../cellpy-core` working copy (branch for #45):
|
|
113
|
+
|
|
114
|
+
1. Full seam pipeline via `tests/test_slim.py` — covers raw load
|
|
115
|
+
(`arbin_res` `from_raw`) → `make_step_table` → `make_summary` →
|
|
116
|
+
golden value (`summary.loc[1, data_point] == 1457`) → `save(.h5)`
|
|
117
|
+
roundtrip, now without any selector import.
|
|
118
|
+
2. Full cellpy test suite: `pytest` (conda `cellpy_dev_313`) — catches any
|
|
119
|
+
other path that indirectly relied on the removed functions or the
|
|
120
|
+
`selector` kwarg plumbing.
|
|
121
|
+
3. Deprecation check: call `make_summary(selector_type="non-cv")` (e.g. in a
|
|
122
|
+
test with `pytest.warns(DeprecationWarning)`) to verify the warning fires
|
|
123
|
+
and the summary still builds.
|
|
124
|
+
4. Sanity import check against edited core:
|
|
125
|
+
`uv run python -c "import cellpycore.selectors as s; assert not hasattr(s, 'create_selector')"`.
|
|
126
|
+
|
|
127
|
+
## Open questions
|
|
128
|
+
|
|
129
|
+
- None — kwargs handling, core-param removal, and cellpy branching resolved by
|
|
130
|
+
user 2026-07-02.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Issue #45 status: remove `create_selector` / `summary_selector_exluder`
|
|
2
|
+
|
|
3
|
+
- [x] Done
|
|
4
|
+
|
|
5
|
+
## What was done (2026-07-02)
|
|
6
|
+
|
|
7
|
+
### cellpy (branch `core45-drop-create-selector`, off `master`)
|
|
8
|
+
|
|
9
|
+
- `cellpy/readers/cellreader.py`:
|
|
10
|
+
- Removed `from cellpycore import selectors as core_selectors`.
|
|
11
|
+
- `make_summary`: kept the `selector` / `selector_type` / `exclude_types` /
|
|
12
|
+
`exclude_steps` kwargs but they now emit a `DeprecationWarning` when
|
|
13
|
+
supplied (they have been no-ops since the core seam); docstring updated.
|
|
14
|
+
- `_make_summary`: dropped the four dead kwargs, the `create_selector`
|
|
15
|
+
block, and the `selector=` forwarding to `make_core_summary`.
|
|
16
|
+
- `tests/test_slim.py`: removed `core_selectors` usage in
|
|
17
|
+
`test_direct_core_make_core_summary`; added
|
|
18
|
+
`test_make_summary_selector_kwargs_deprecated` (asserts warning + summary
|
|
19
|
+
still builds).
|
|
20
|
+
|
|
21
|
+
### cellpy-core (branch `45-cleanup-blocked-...`)
|
|
22
|
+
|
|
23
|
+
- `src/cellpycore/selectors.py`: deleted `create_selector` and
|
|
24
|
+
`summary_selector_exluder`, plus now-unused imports (`functools`,
|
|
25
|
+
`Callable`, `Iterable`, `List`, `StepCols`, `RawCols`) and the
|
|
26
|
+
`FIRST`/`LAST`/`DELTA` constants.
|
|
27
|
+
- `src/cellpycore/cell_core.py`: removed the never-used `selector` parameter
|
|
28
|
+
from both `make_core_summary` signatures (native + legacy bridge).
|
|
29
|
+
- `tests/test_schema.py`: added `test_no_legacy_selector_functions`.
|
|
30
|
+
- Docs: `selector-dead-code-deferral.md` marked resolved;
|
|
31
|
+
`cellpy-core-integration-roadmap.md` #45 row flipped to done.
|
|
32
|
+
|
|
33
|
+
## Test results
|
|
34
|
+
|
|
35
|
+
- cellpy-core: `uv run pytest` — **95 passed** (includes golden fixtures).
|
|
36
|
+
- cellpy (conda `cellpy_dev_313`, editable core via `[tool.uv.sources]`):
|
|
37
|
+
- `tests/test_slim.py` — 6 passed (incl. new deprecation test).
|
|
38
|
+
- `pytest -k summary` — 79 passed, 1 skipped, 1 xfailed.
|
|
39
|
+
- Full suite (excluding `test_ica.py`, `test_ocv_relax.py`,
|
|
40
|
+
`test_plotutils_summary_plot.py`) — **428 passed, 17 skipped, 11 xfailed**.
|
|
41
|
+
|
|
42
|
+
### Pre-existing environment crash (not caused by this change)
|
|
43
|
+
|
|
44
|
+
`test_ica.py`, `test_ocv_relax.py`, and `test_plotutils_summary_plot.py`
|
|
45
|
+
abort the interpreter with `Windows fatal exception: code 0xc06d007f` inside
|
|
46
|
+
scipy/numpy LAPACK (`lstsq` / `inv`). A standalone
|
|
47
|
+
`python -c "from scipy.signal import savgol_filter; ..."` (no cellpy imports)
|
|
48
|
+
crashes the same way in `cellpy_dev_313`, so this is a broken scipy/BLAS DLL
|
|
49
|
+
situation in that conda env on this machine, unrelated to the selector
|
|
50
|
+
removal. Should be fixed separately (e.g. reinstall scipy/numpy in the env).
|
|
51
|
+
|
|
52
|
+
## Remaining work
|
|
53
|
+
|
|
54
|
+
- Commit + push both branches, open PRs.
|
|
55
|
+
- **Merge order:** cellpy PR first (cellpy pins `cellpycore @ git+…@main`),
|
|
56
|
+
then the cellpy-core PR.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Issue #54: Native exclude-types summary support (replace removed create_selector exclusion feature)
|
|
2
|
+
|
|
3
|
+
Source: https://github.com/cellpy/cellpy-core/issues/54
|
|
4
|
+
|
|
5
|
+
## Original issue text
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Issue #45 removed the legacy pandas selector pair (`create_selector` / `summary_selector_exluder`). The default row selection (one cycle-end datapoint per cycle) was already native in `summarizers.make_summary`, so nothing was lost there.
|
|
10
|
+
|
|
11
|
+
But the old selector had a second, distinct capability that was never ported to the polars engine (and has been silently a no-op since the core seam landed): **exclude-types summaries** (`selector_type="non-cv" / "non-rest" / "non-ocv" / "only-cv"`). Because capacities are cycle-cumulative, this is not row selection — it subtracts the excluded steps' deltas (`last - first` per step, summed per cycle) from the cycle-end values, producing a summary "as if" those steps never happened.
|
|
12
|
+
|
|
13
|
+
cellpy's `make_summary(selector_type=...)` kwargs currently emit a `DeprecationWarning` and do nothing.
|
|
14
|
+
|
|
15
|
+
## Proposed design (concrete first, KISS)
|
|
16
|
+
|
|
17
|
+
Add an option to the native engine:
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
summarizers.make_summary(data, schema, exclude_step_types=["cv_"], ...)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Implementation sketch:
|
|
24
|
+
|
|
25
|
+
1. Filter the step table by excluded `step_type` prefix(es).
|
|
26
|
+
2. Compute per-step deltas from the existing `*_first` / `*_last` stat columns (charge, discharge, current, voltage).
|
|
27
|
+
3. Group by cycle (and `test_id` when present), sum.
|
|
28
|
+
4. Subtract the per-cycle correction from the selected cycle-end summary rows.
|
|
29
|
+
|
|
30
|
+
No new protocol/abstraction yet. If a second variant appears (custom exclusion logic, different correction policy), promote it to a pluggable `SummaryAdjuster` mirroring `extractors.SummaryExtractor` — giving the clean vocabulary: *selectors* pick rows, *extractors* derive columns, *adjusters* correct values.
|
|
31
|
+
|
|
32
|
+
## Testing
|
|
33
|
+
|
|
34
|
+
- Parity test against the removed pandas implementation (resurrect `summary_selector_exluder` from git history as a test oracle on a fixture with CV steps).
|
|
35
|
+
- Guard: `exclude_step_types=None` must stay byte-identical to the current summary (golden fixtures).
|
|
36
|
+
|
|
37
|
+
## Follow-up on the cellpy side
|
|
38
|
+
|
|
39
|
+
Once this lands, cellpy can wire `selector_type` / `exclude_types` / `exclude_steps` to the new argument instead of warning, or keep the deprecation and expose the new API directly.
|
|
40
|
+
|
|
41
|
+
## Links
|
|
42
|
+
|
|
43
|
+
- #45 (dead-code removal that surfaced this)
|
|
44
|
+
- #13 (polars summary rewrite that deliberately skipped the exclusion machinery)
|
|
45
|
+
- `.issueflows/04-designs-and-guides/selector-dead-code-deferral.md`
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Plan — Issue #54: Native exclude-types summary support
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Add native exclude-types summary support to the polars engine: `summarizers.make_summary(..., exclude_step_types=["cv_"])` subtracts the excluded steps' per-cycle deltas from the cycle-end summary values, replacing the capability lost when `create_selector` / `summary_selector_exluder` were removed (issue #45).
|
|
6
|
+
|
|
7
|
+
## Constraints
|
|
8
|
+
|
|
9
|
+
- KISS: concrete kwarg first, no `SummaryAdjuster` protocol yet (issue explicitly defers it until a second variant appears).
|
|
10
|
+
- `exclude_step_types=None` (default) must be **byte-identical** to today's summary — no join, no extra columns, golden fixtures untouched.
|
|
11
|
+
- Engine stays schema-injected, polars-native, thread-safe; no module-level state.
|
|
12
|
+
- cellpy-side wiring (`selector_type` → this kwarg) is a follow-up in the cellpy repo, out of scope here (per migration guide: core PR first).
|
|
13
|
+
- Google-style docstrings.
|
|
14
|
+
|
|
15
|
+
### Prior art
|
|
16
|
+
|
|
17
|
+
- **Oracle:** removed pandas `summary_selector_exluder` recovered from `git show 2da165e^:src/cellpycore/selectors.py`. Math: filter steps whose `step_type` starts with any excluded prefix; per step compute `last - first` for current, voltage, charge, discharge; group by cycle, sum; left-merge onto selected cycle-end raw rows, `fillna(0.0)`, subtract.
|
|
18
|
+
- **Deviations to document:** (1) old code also corrected current and voltage on the raw rows — the native summary's base subset carries only capacities (end potentials come from step-table joins), so the native correction targets `charge_capacity` / `discharge_capacity` only; (2) old `exclude_steps` matched step *numbers* against the step **type** column (`steps[t_st_txt].isin(exclude_steps)`) — a latent bug; we do not port `exclude_steps` at all; (3) old `create_selector` mapped `"non-rest"` → prefix `"rest_"` which never matched label `"rest"` — mapping strings stay in cellpy's follow-up, core takes explicit prefixes.
|
|
19
|
+
- **Siblings/conventions to mirror:** `_group_keys` / `use_tid` composite-key handling and `join ... how="left"` + `fill_null` pattern already used by `_add_end_potentials`, `c_rates_to_summary`, `ir_to_summary` in [summarizers.py](../../src/cellpycore/summarizers.py). Step table provides `charge_capacity_first/_last`, `discharge_capacity_first/_last` stat columns (native names). Do **not** reuse `_delta_expr` (it is percent-based); the correction needs plain `last - first`.
|
|
20
|
+
- Toolbox `.issueflows/00-tools/`: empty — nothing to reuse.
|
|
21
|
+
- Graph: Community 50 (`make_summary`, `_group_keys`, `_add_end_potentials`) and 53 (step table) confirm the touch points; no surprises.
|
|
22
|
+
|
|
23
|
+
## Approach
|
|
24
|
+
|
|
25
|
+
1. **`summarizers.make_summary`** gains `exclude_step_types: Optional[Sequence[str]] = None`.
|
|
26
|
+
- When `None`: current code path, untouched.
|
|
27
|
+
- Else, right after the base `summary = selected.select(...)` and **before** the CE / coulombic-difference / loss / cumulated `with_columns` (so every derived column reflects corrected capacities, mirroring the oracle which corrected raw rows before summary derivation):
|
|
28
|
+
- Filter steps: `pl.any_horizontal(pl.col(shdr.step_type).str.starts_with(p) for p in exclude_step_types)`.
|
|
29
|
+
- Aggregate per `(test_id?, cycle)` (via `_group_keys`): `(charge_capacity_last - charge_capacity_first).sum()` and same for discharge, into temp `__excl_charge` / `__excl_discharge` columns.
|
|
30
|
+
- Left-join onto summary (same `use_tid` join-key logic as `_add_end_potentials`), `fill_null(0.0)` (oracle's `replace_nan=True`), subtract from `chdr.charge_capacity` / `chdr.discharge_capacity`, drop temp columns.
|
|
31
|
+
2. **`CellpyCellCore.make_core_summary`** in [cell_core.py](../../src/cellpycore/cell_core.py) gains the same kwarg and passes it through (native entry point). Legacy bridge `OldCellpyCellCore` untouched for now — see open questions.
|
|
32
|
+
3. Docstrings updated; short note added to `.issueflows/04-designs-and-guides/selector-dead-code-deferral.md` marking #54 resolved once merged (done at close, not plan).
|
|
33
|
+
|
|
34
|
+
## Files to touch
|
|
35
|
+
|
|
36
|
+
- `src/cellpycore/summarizers.py` — new kwarg + correction block in `make_summary` (~30 lines).
|
|
37
|
+
- `src/cellpycore/cell_core.py` — pass-through kwarg on `CellpyCellCore.make_core_summary`.
|
|
38
|
+
- `tests/test_schema.py` (or new `tests/test_exclude_types.py` if cleaner) — new tests, see below.
|
|
39
|
+
|
|
40
|
+
## Test strategy
|
|
41
|
+
|
|
42
|
+
Command: `uv run pytest` (project venv).
|
|
43
|
+
|
|
44
|
+
- **Parity vs oracle:** synthetic native-named raw with CV steps (extend the `_build_cumulative_raw`-style builders; golden Arbin fixture has *no* CV steps, so it can't drive parity). Inline a small pandas oracle in the test file — the resurrected `summary_selector_exluder` math ported to native column names, capacities only — and assert the native `exclude_step_types=["cv_"]` summary capacities match.
|
|
45
|
+
- **Guard:** `exclude_step_types=None` output equals current summary frame exactly (and existing golden tests `test_golden.py` stay green).
|
|
46
|
+
- **Edge:** cycle without any excluded step gets zero correction (fill_null path); merged two-test frame keeps corrections isolated per `test_id` (reuse `_build_merged_raw` pattern).
|
|
47
|
+
- **`only-cv` analogue:** `exclude_step_types=["charge", "discharge"]` excludes the plain `charge` / `discharge` steps but keeps `cv_charge` / `cv_discharge` (neither starts with those prefixes) — a test locks this `startswith` semantics, matching the oracle.
|
|
48
|
+
|
|
49
|
+
## Open questions
|
|
50
|
+
|
|
51
|
+
1. **Legacy bridge:** should `OldCellpyCellCore.make_core_summary` also accept/forward `exclude_step_types` now (making cellpy's follow-up wiring trivial), or stay untouched until the cellpy-side issue? Recommendation: add the pass-through now — it is ~3 lines and the bridge is the path cellpy actually calls.
|
|
52
|
+
2. **Correction scope:** confirm capacities-only is acceptable (old code also adjusted the raw current/voltage of the selected row; those adjusted values fed nothing that survives in the native summary). Recommendation: capacities only, documented.
|
|
53
|
+
3. Branch: create `54-exclude-types-summary` off up-to-date `main` at `/iflow-start`.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Issue #54 status — Native exclude-types summary support
|
|
2
|
+
|
|
3
|
+
- [x] Done
|
|
4
|
+
|
|
5
|
+
## What's done
|
|
6
|
+
|
|
7
|
+
- 2026-07-02: plan accepted (`issue54_plan.md`); branch `54-exclude-types-summary` created off up-to-date `main`.
|
|
8
|
+
- 2026-07-02: implemented per plan:
|
|
9
|
+
- `summarizers.make_summary` gained `exclude_step_types: Optional[Sequence[str]] = None`; new helper `_subtract_excluded_step_deltas` subtracts excluded steps' per-cycle `last - first` capacity deltas (prefix match on `step_type`, `_group_keys`-aware, `fill_null(0.0)`) from the cycle-end capacities **before** CE / loss / cumulated columns are derived.
|
|
10
|
+
- Pass-through kwarg on `CellpyCellCore.make_core_summary` and `OldCellpyCellCore.make_core_summary` (legacy bridge, per accepted open question 1).
|
|
11
|
+
- Capacities-only correction (accepted open question 2); documented in the helper docstring.
|
|
12
|
+
- New `tests/test_exclude_types.py` (7 tests): parity vs inline pandas oracle (resurrected `summary_selector_exluder` math), derived-column correctness, `None`/`[]` guard, unmatched-prefix zero correction, cycle-without-excluded-step, `startswith` ("only-cv") semantics lock, merged two-test isolation.
|
|
13
|
+
- Full suite green: 107 passed (golden fixtures untouched → `None` path byte-identical).
|
|
14
|
+
|
|
15
|
+
## Remaining work
|
|
16
|
+
|
|
17
|
+
- None in this repo. Cellpy-side follow-up (wire `selector_type` / `exclude_types`
|
|
18
|
+
to the new kwarg instead of the bare `DeprecationWarning`) is a separate issue in
|
|
19
|
+
jepegit/cellpy. `selector-dead-code-deferral.md` note updated at close.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Issue #55: Add validating front door for raw frames (Data.from_raw_frame)
|
|
2
|
+
|
|
3
|
+
Source: https://github.com/cellpy/cellpy-core/issues/55
|
|
4
|
+
|
|
5
|
+
## Original issue text
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
The slim-consumer story (a user who builds a polars DataFrame in the native `config.RawCols` schema themselves and wants step/cycle summaries straight from cellpy-core, without cellpy) currently has no validating entry point:
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
core = CellpyCellCore(initialize=True)
|
|
13
|
+
core.data.raw = df # accepts anything
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
A wrong column name or dtype only fails deep inside a polars expression in `summarizers`, with an error message that does not point back at the actual problem (the input frame not matching the schema).
|
|
17
|
+
|
|
18
|
+
## Proposal
|
|
19
|
+
|
|
20
|
+
Add a small validating constructor on `Data` (in `src/cellpycore/cell_core.py`):
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
data = Data.from_raw_frame(df, validate=True)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Behavior:
|
|
27
|
+
|
|
28
|
+
- Wraps the frame in a fresh `Data` (with the usual `MockMetaTestDependent`, so the graceful-degradation metadata guarantee is untouched).
|
|
29
|
+
- When `validate=True` (default), checks the frame against `config.RawCols`:
|
|
30
|
+
- required columns present (clear error listing missing ones);
|
|
31
|
+
- dtype sanity for the load-bearing columns, in particular `epoch_time_utc` must be int64 (ns, UTC — the STEP-11 contract) and datapoint/cycle/step numbers integer;
|
|
32
|
+
- optional columns (`test_id`, `internal_resistance`, …) allowed absent.
|
|
33
|
+
- Fails fast with a single actionable error message instead of a deep polars stack trace.
|
|
34
|
+
|
|
35
|
+
Keep it KISS: one classmethod + one module-level validation helper, no schema-validation framework.
|
|
36
|
+
|
|
37
|
+
## Tests
|
|
38
|
+
|
|
39
|
+
- Happy path: valid native frame round-trips through `make_step_table` + `make_summary` identically to plain `data.raw = df`.
|
|
40
|
+
- Missing column → error naming the missing column(s).
|
|
41
|
+
- Wrong dtype on `epoch_time_utc` → error mentioning the int64-ns contract.
|
|
42
|
+
- `validate=False` skips checks entirely.
|
|
43
|
+
|
|
44
|
+
## Links
|
|
45
|
+
|
|
46
|
+
- Raised while discussing the future slim-consumer / cellpy v2 interaction pattern (roadmap doc `cellpy-core-integration-roadmap.md`).
|
|
47
|
+
- Related: #42 (reset-granularity normalization is the other half of "arbitrary external raw frames").
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Plan — Issue #55: Add validating front door for raw frames (`Data.from_raw_frame`)
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Give slim consumers a validating entry point for native-schema polars raw frames:
|
|
6
|
+
`Data.from_raw_frame(df, validate=True)` fails fast with one actionable error
|
|
7
|
+
instead of a deep polars stack trace inside `summarizers`.
|
|
8
|
+
|
|
9
|
+
## Constraints
|
|
10
|
+
|
|
11
|
+
- KISS (per issue): one classmethod + one module-level validation helper in
|
|
12
|
+
`src/cellpycore/cell_core.py`. No schema-validation framework, no new deps.
|
|
13
|
+
- Graceful-degradation metadata guarantee untouched: `Data()` already attaches
|
|
14
|
+
`MockMetaTestDependent`; `from_raw_frame` reuses the plain constructor.
|
|
15
|
+
- `validate=False` must skip all checks entirely (zero cost).
|
|
16
|
+
- Google-style docstrings.
|
|
17
|
+
|
|
18
|
+
### Prior art
|
|
19
|
+
|
|
20
|
+
- `tests/test_harmonized_fixture.py::_rawcols_names()` — derives the full
|
|
21
|
+
`RawCols` name set via `vars(RawCols)`; the helper mirrors the idea but only
|
|
22
|
+
needs the explicit required subset (coexist, no migration).
|
|
23
|
+
- `summarizers._ensure_test_id` — engine already auto-adds `test_id`; validator
|
|
24
|
+
must therefore treat `test_id` as optional.
|
|
25
|
+
- `summarizers.make_step_table` signal resolution (lines ~360-375) — engine
|
|
26
|
+
skips absent `internal_resistance` / `ref_potential` / `step_time`; validator
|
|
27
|
+
treats these as optional too.
|
|
28
|
+
- `_helpers.create_raw_data()` + `mock_data_with_raw` fixture — valid native
|
|
29
|
+
frame for tests (reuse, no new fixture needed).
|
|
30
|
+
- Toolbox (`.issueflows/00-tools/`) empty; graph report checked — nothing else relevant.
|
|
31
|
+
|
|
32
|
+
## Approach
|
|
33
|
+
|
|
34
|
+
1. **Module-level helper** `validate_raw_frame(raw, raw_cols=None)` in
|
|
35
|
+
`cell_core.py` (public, so cellpy v2 can call it directly later):
|
|
36
|
+
- `raw_cols` defaults to `config.RawCols()`.
|
|
37
|
+
- Type check: must be a `polars.DataFrame` (the slim-consumer story is
|
|
38
|
+
polars-native) — clear `TypeError` otherwise.
|
|
39
|
+
- **Required columns** (the engine's load-bearing set):
|
|
40
|
+
`datapoint_num`, `cycle_num`, `step_num`, `epoch_time_utc`, `test_time`,
|
|
41
|
+
`current`, `potential`, `cumulative_charge_capacity`,
|
|
42
|
+
`cumulative_discharge_capacity`. Missing ones → single `ValueError`
|
|
43
|
+
listing all of them.
|
|
44
|
+
- **Dtype sanity** (collected, reported together with missing-column errors
|
|
45
|
+
in one message):
|
|
46
|
+
- `epoch_time_utc` must be exactly `pl.Int64` — error text mentions the
|
|
47
|
+
int64 nanoseconds-since-epoch UTC (STEP-11) contract.
|
|
48
|
+
- `datapoint_num`, `cycle_num`, `step_num` must be integer dtypes.
|
|
49
|
+
- `test_time`, `current`, `potential`, `cumulative_*_capacity` must be
|
|
50
|
+
numeric.
|
|
51
|
+
- **Optional columns** (`test_id`, `internal_resistance`, `ref_potential`,
|
|
52
|
+
`step_time`, `mask`, `source_*`, aux columns, …): allowed absent, not
|
|
53
|
+
dtype-checked (KISS).
|
|
54
|
+
2. **Classmethod** on `Data`:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
@classmethod
|
|
58
|
+
def from_raw_frame(cls, raw, validate=True, raw_cols=None) -> "Data":
|
|
59
|
+
if validate:
|
|
60
|
+
validate_raw_frame(raw, raw_cols)
|
|
61
|
+
data = cls()
|
|
62
|
+
data.raw = raw
|
|
63
|
+
return data
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
3. Run `graphify update .` after the code change (project rule).
|
|
67
|
+
|
|
68
|
+
## Files to touch
|
|
69
|
+
|
|
70
|
+
- [src/cellpycore/cell_core.py](c:\scripting\cellpy-core\src\cellpycore\cell_core.py)
|
|
71
|
+
— add `validate_raw_frame()` helper + `Data.from_raw_frame()` classmethod
|
|
72
|
+
(imports `polars` lazily inside the helper, matching module style).
|
|
73
|
+
- [tests/test_creation.py](c:\scripting\cellpy-core\tests\test_creation.py)
|
|
74
|
+
— add the new tests (creation-themed file already exists; no new test module).
|
|
75
|
+
|
|
76
|
+
## Test strategy
|
|
77
|
+
|
|
78
|
+
Command: `uv run pytest` (project default).
|
|
79
|
+
|
|
80
|
+
New tests in `tests/test_creation.py`:
|
|
81
|
+
|
|
82
|
+
- **Happy path / round-trip**: `Data.from_raw_frame(create_raw_data())` runs
|
|
83
|
+
through `CellpyCellCore.make_core_step_table` + `make_core_summary` and the
|
|
84
|
+
resulting steps/summary frames equal those from plain `data.raw = df`.
|
|
85
|
+
- **Missing columns**: drop e.g. `cycle_num` + `current` → `ValueError` naming
|
|
86
|
+
both.
|
|
87
|
+
- **Wrong dtype**: cast `epoch_time_utc` to `pl.Float64` → error mentioning
|
|
88
|
+
int64-ns contract.
|
|
89
|
+
- **`validate=False`**: same broken frame passes without error.
|
|
90
|
+
- **Not a polars frame**: pandas frame → `TypeError`.
|
|
91
|
+
|
|
92
|
+
## Open questions
|
|
93
|
+
|
|
94
|
+
- None — polars-only input is assumed (the issue's slim-consumer story);
|
|
95
|
+
pandas users go through the legacy bridge instead.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Issue #55 status — validating front door for raw frames
|
|
2
|
+
|
|
3
|
+
Branch: `55-from-raw-frame`
|
|
4
|
+
|
|
5
|
+
## Done
|
|
6
|
+
|
|
7
|
+
- 2026-07-02: Added `validate_raw_frame()` module-level helper and
|
|
8
|
+
`Data.from_raw_frame(raw, validate=True, raw_cols=None)` classmethod in
|
|
9
|
+
`src/cellpycore/cell_core.py` (per confirmed `issue55_plan.md`):
|
|
10
|
+
- `TypeError` on non-polars input (pandas users -> legacy bridge).
|
|
11
|
+
- Single `ValueError` collecting all problems: missing required columns
|
|
12
|
+
(`datapoint_num`, `cycle_num`, `step_num`, `epoch_time_utc`, `test_time`,
|
|
13
|
+
`current`, `potential`, `cumulative_charge_capacity`,
|
|
14
|
+
`cumulative_discharge_capacity`), `epoch_time_utc` must be Int64
|
|
15
|
+
(STEP-11 int64-ns UTC contract named in the message), datapoint/cycle/step
|
|
16
|
+
integer, rest numeric.
|
|
17
|
+
- Optional columns (`test_id`, `internal_resistance`, `ref_potential`,
|
|
18
|
+
`step_time`, `source_*`, `aux_*`, …) allowed absent, not dtype-checked.
|
|
19
|
+
- `validate=False` skips all checks; fresh `Data()` keeps the
|
|
20
|
+
`MockMetaTestDependent` graceful-degradation guarantee.
|
|
21
|
+
- 5 new tests in `tests/test_creation.py`: round-trip parity vs plain
|
|
22
|
+
`data.raw = df` through `make_core_step_table` + `make_core_summary`,
|
|
23
|
+
missing columns all named, wrong epoch dtype mentions int64-ns,
|
|
24
|
+
`validate=False` skip, pandas `TypeError`.
|
|
25
|
+
- Test suite green: `uv run pytest` -> 100 passed.
|
|
26
|
+
- `graphify update .` run after the code change.
|
|
27
|
+
|
|
28
|
+
## Remaining
|
|
29
|
+
|
|
30
|
+
- Nothing (ready for `/iflow-close`).
|
|
31
|
+
|
|
32
|
+
## Status
|
|
33
|
+
|
|
34
|
+
- [x] Done
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Issue #56: Document standalone use of cellpy-core (slim-consumer guide)
|
|
2
|
+
|
|
3
|
+
Source: https://github.com/cellpy/cellpy-core/issues/56
|
|
4
|
+
|
|
5
|
+
## Original issue text
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
cellpy-core is designed to be usable on its own: anyone who can produce a polars DataFrame in the native `config.RawCols` schema should be able to get step tables and per-cycle summaries without pulling in full cellpy. That story currently lives only in design docs and code docstrings — there is no user-facing documentation for it.
|
|
10
|
+
|
|
11
|
+
## Proposal
|
|
12
|
+
|
|
13
|
+
Add a "Using cellpy-core standalone" guide to `docs/` covering:
|
|
14
|
+
|
|
15
|
+
### 1. The recommended entry point
|
|
16
|
+
|
|
17
|
+
Native `CellpyCellCore` (not the `OldCellpyCellCore` legacy bridge, which exists only to serve legacy cellpy headers):
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from cellpycore.cell_core import CellpyCellCore, Data
|
|
21
|
+
|
|
22
|
+
core = CellpyCellCore(initialize=True)
|
|
23
|
+
core.data.raw = my_polars_frame # native config.RawCols schema
|
|
24
|
+
core.cycle_mode = "anode" # only for half-cells; default "standard"
|
|
25
|
+
|
|
26
|
+
data = core.make_core_step_table(
|
|
27
|
+
core.data,
|
|
28
|
+
nom_cap=my_nom_cap_abs, # absolute Ah, for the per-step C-rate
|
|
29
|
+
raw_limits=my_instrument_limits, # optional; DEFAULT_RAW_LIMITS otherwise
|
|
30
|
+
)
|
|
31
|
+
data = core.make_core_summary(
|
|
32
|
+
data,
|
|
33
|
+
current_conversion_factor=1.0, # raw-current -> output-current, by value
|
|
34
|
+
)
|
|
35
|
+
# optional: specific / normalized columns
|
|
36
|
+
data = core.add_scaled_summary_columns(
|
|
37
|
+
data,
|
|
38
|
+
nom_cap_abs=my_nom_cap_abs,
|
|
39
|
+
normalization_cycles=None,
|
|
40
|
+
specific_converters={"gravimetric": f_g, "areal": f_a, "absolute": f_abs},
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
steps, summary = data.steps, data.summary # polars frames (StepCols / CycleCols)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Also mention the class-free alternative (`summarizers.make_step_table(data)` + `summarizers.make_summary(data)` with the default schema) and when the class is worth it (cycle-mode -> TestMode handling, IR/C-rate orchestration).
|
|
47
|
+
|
|
48
|
+
### 2. The contract the caller must honor
|
|
49
|
+
|
|
50
|
+
- **Order matters:** step table before summary (`make_summary` reads `data.steps`).
|
|
51
|
+
- **No metadata required:** `Data()` ships `MockMetaTestDependent`; only `cycle_mode` changes the math (CE direction).
|
|
52
|
+
- **Units by value:** core never sees unit objects — the caller precomputes floats (`nom_cap`, `current_conversion_factor`, `specific_converters`); pint fallback only via the optional `units` extra.
|
|
53
|
+
- **Raw shape assumptions:** `epoch_time_utc` is int64 ns UTC; capacities are cycle-cumulative per direction (point at `normalize_capacity_granularity` for step-/test-cumulative inputs); `test_id` optional, defaults to 0.
|
|
54
|
+
- **Legacy cruft absent by design:** native summary is the clean `CycleCols` subset + C-rate/IR; cumulated CE / shifted / RIC columns exist only on the legacy bridge.
|
|
55
|
+
|
|
56
|
+
### 3. Housekeeping
|
|
57
|
+
|
|
58
|
+
- Link the guide from the README.
|
|
59
|
+
- Once #55 (`Data.from_raw_frame`) lands, switch the example to use it.
|
|
60
|
+
|
|
61
|
+
## Links
|
|
62
|
+
|
|
63
|
+
- Raised together with #55 while discussing the future slim-consumer / cellpy v2 interaction pattern.
|
|
64
|
+
- Background: `.issueflows/04-designs-and-guides/cellpy-core-integration-roadmap.md`, `cellpy-core-migration.md` §4 (metadata/units boundaries).
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Issue #56 — plan
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Add a user-facing "Using cellpy-core standalone" guide to `docs/` so slim consumers
|
|
6
|
+
(anyone with a polars frame in the native `config.RawCols` schema) can get step
|
|
7
|
+
tables and per-cycle summaries without full cellpy. Link it from the README.
|
|
8
|
+
|
|
9
|
+
## Approach
|
|
10
|
+
|
|
11
|
+
- New `docs/standalone-use.md` covering:
|
|
12
|
+
- Recommended entry point: native `CellpyCellCore` + `Data.from_raw_frame`
|
|
13
|
+
(#55 landed, so the example uses the validating front door, not bare
|
|
14
|
+
`core.data.raw = ...`).
|
|
15
|
+
- Full pipeline example: `make_core_step_table` (nom_cap, raw_limits) →
|
|
16
|
+
`make_core_summary` (current_conversion_factor, exclude_step_types) →
|
|
17
|
+
optional `add_scaled_summary_columns` (specific_converters).
|
|
18
|
+
- Class-free alternative: `summarizers.make_step_table` + `summarizers.make_summary`
|
|
19
|
+
with the default schema, and when the class is worth it (cycle_mode → TestMode,
|
|
20
|
+
IR/C-rate orchestration).
|
|
21
|
+
- Caller contract: step table before summary; no metadata required; units by
|
|
22
|
+
value (pint only via the optional `units` extra); raw-shape assumptions
|
|
23
|
+
(`epoch_time_utc` int64 ns UTC, cycle-cumulative capacities →
|
|
24
|
+
`normalize_capacity_granularity` for step-/test-cumulative inputs, `test_id`
|
|
25
|
+
optional); legacy cruft only on the `OldCellpyCellCore` bridge.
|
|
26
|
+
- Links to `docs/data_format_specifications/harmonized_raw.md` and
|
|
27
|
+
`docs/data-object-definition.md`.
|
|
28
|
+
- README: add a short Documentation section linking the guide (and install note —
|
|
29
|
+
package is on PyPI as `cellpycore` since v0.1.1, README still says GitHub-only;
|
|
30
|
+
fix that line while touching it).
|
|
31
|
+
|
|
32
|
+
## Files to touch
|
|
33
|
+
|
|
34
|
+
- `docs/standalone-use.md` (new)
|
|
35
|
+
- `README.md` (link + install line)
|
|
36
|
+
- `.issueflows/01-current-issues/issue56_*.md` (tracking)
|
|
37
|
+
- `HISTORY.md`, `pyproject.toml` (at close: patch bump + promote)
|
|
38
|
+
|
|
39
|
+
## Test strategy
|
|
40
|
+
|
|
41
|
+
Docs-only change — no engine code touched. Re-run `uv run pytest` (107 tests) to
|
|
42
|
+
confirm the suite stays green; verify the example snippets against the real
|
|
43
|
+
signatures in `cell_core.py` / `summarizers.py` (done while writing).
|
|
44
|
+
|
|
45
|
+
## Design docs consulted
|
|
46
|
+
|
|
47
|
+
`cellpy-core-integration-roadmap.md`, `cellpy-core-migration.md` §4,
|
|
48
|
+
`release-procedure.md` (for the close/release steps).
|