Skip to content

fix: labelled DataFrames for IRF / FEVD / HD result accessors (closes #72) - #73

Merged
thomaspinder merged 1 commit into
mainfrom
audit/01-labelled-results
May 18, 2026
Merged

thomaspinder merged 1 commit into
mainfrom
audit/01-labelled-results

Conversation

@thomaspinder

Copy link
Copy Markdown
Collaborator

Summary

  • IRF/FEVD .median() / .hdi() return wide DataFrames with MultiIndex(['response','shock']) on columns, integer horizon index.
  • HD .median() / .hdi() now indexed by DatetimeIndex (recovered via a new time coord on the underlying DataArray), with the same MultiIndex columns — the (T, response, shock) axes are no longer collapsed.
  • _irf.py switches from col_idx = i*n_vars + j integer arithmetic to label-based med[(resp, shock)] selection.

Resolves audit findings #1 (collapsed named axes) and #10 (HD time axis lost) — see reports/audit-2026-05-18.md. First of four stacked PRs from plans/2026-05-18-audit-cleanup-plan.md.

Closes #72.

Test plan

  • uv run python -m pytest tests/test_results.py -v — 21/21 pass; 9 new tests cover the new contract for IRF/FEVD/HD (round-trip values via label selection, MultiIndex(['response','shock']) columns, HD DatetimeIndex rows, HDIResult mirrors .median() shape and labels).
  • make test — 268/268 pass (incl. slow MCMC).
  • make check — ruff + ty clean.
  • make docs-render-ci — all 5 tutorials render, exit 0.
  • test_identified.py / test_plotting.py unchanged: shape (11, 4) survives; values unchanged.

🤖 Generated with Claude Code

…72)

Previously, IRFResult/FEVDResult/HistoricalDecompositionResult collapsed
the named (response, shock) axes into anonymous integer columns, and HD
also lost its time axis via the (T*n, n) reshape. Callers had to reverse-
engineer the flatten order, and per-row HD access silently misaligned.

- src/impulso/results.py: add `_wide_frame` helper; rewrite IRF/FEVD/HD
  `.median()` and `.hdi()` to return wide DataFrames with
  `MultiIndex(['response','shock'])` on columns; integer horizon index for
  IRF/FEVD, DatetimeIndex for HD. `.to_dataframe()` stays as a `.median()`
  passthrough pending the dedicated follow-up (audit #9).
- src/impulso/identified.py: attach `"time"` coord on the HD DataArray
  so the new HD accessor can build its DatetimeIndex.
- src/impulso/plotting/_irf.py: replace `med.values[:, col_idx]` integer
  arithmetic with label-based `med[(resp, shock)]` lookups; pull shock
  names from the DataArray's `shock` coord.
- tests/test_results.py: 9 new tests across IRF/FEVD/HD locking the new
  contract — MultiIndex column labels round-trip the underlying
  DataArray values, HD index is a DatetimeIndex matching `data.index[n_lags:]`,
  HDIResult.lower / .upper mirror shape and labels.

Closes audit findings #1 and #10 (reports/audit-2026-05-18.md).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.3%. Comparing base (33d4caf) to head (ddc5683).

Additional details and impacted files
@@           Coverage Diff           @@
##            main     #73     +/-   ##
=======================================
+ Coverage   92.4%   93.3%   +0.9%     
=======================================
  Files         26      26             
  Lines       1141    1148      +7     
  Branches     111     111             
=======================================
+ Hits        1055    1072     +17     
+ Misses        65      55     -10     
  Partials      21      21             

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@thomaspinder
thomaspinder merged commit d527d44 into main May 18, 2026
14 checks passed
@thomaspinder
thomaspinder deleted the audit/01-labelled-results branch May 18, 2026 21:43
thomaspinder added a commit that referenced this pull request May 18, 2026
Wraps up the spring-cleaning stack. Individually small fixes that
cluster naturally into one style PR.

- src/impulso/volatility.py: `Constant.cholesky_path` /
  `forecast_cholesky_path` docstrings reference `L` (the actual
  posterior key after #69) instead of `Sigma`; cross-ref
  `Constant.cholesky_at` as the canonical accessor.
- src/impulso/sv/data.py: `_MIN_OBS` is now `ClassVar[int] = 24` —
  makes the class-attribute intent explicit instead of relying on
  Pydantic's implicit underscore handling.
- src/impulso/fitted.py: `FittedVAR.has_exog` drops `@computed_field`
  (now a plain `@property`) so it stops appearing in `model_dump()`.
- src/impulso/sv/dynamics.py: `RandomWalk.build_latent_path` /
  `AR1.build_latent_path` swap `Any` for `"pt.TensorVariable"` forward
  refs that match the SVDynamics Protocol declaration; drop the
  now-unused `Any` import.
- src/impulso/results.py: delete `VARResultBase.__repr__` override —
  Pydantic's default produces a useful compact repr because every
  `idata` field has `Field(repr=False)`.
- src/impulso/**/*.py: docstring sweep — double backticks (RST) → single
  backticks (Markdown / mkdocstrings); no more `:meth:` / `:class:`
  cross-refs (replaced with plain backticked names in earlier passes).
- CLAUDE.md: codify the docstring convention under "Code Conventions".
- src/impulso/identified.py: delete
  `forecast_error_variance_decomposition`; `fevd` is the canonical
  name. Docstring + .qmd / .md cross-references updated.
- pyproject.toml + uv.lock: bump `0.0.5 → 0.0.6` to ship the cumulative
  audit cleanup (#73 + #75 + #77 + this PR).

Closes audit findings #5, #8, #12, #13, #14, #15, #16
(reports/audit-2026-05-18.md).

Breaking (pre-v0.1): callers of
`IdentifiedVAR.forecast_error_variance_decomposition` must use
`IdentifiedVAR.fevd` (no signature change). The long name was always
an alias; per repo policy pre-v0.1 API breaks are in scope.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
thomaspinder added a commit that referenced this pull request May 18, 2026
Wraps up the spring-cleaning stack. Individually small fixes that
cluster naturally into one style PR.

- src/impulso/volatility.py: `Constant.cholesky_path` /
  `forecast_cholesky_path` docstrings reference `L` (the actual
  posterior key after #69) instead of `Sigma`; cross-ref
  `Constant.cholesky_at` as the canonical accessor.
- src/impulso/sv/data.py: `_MIN_OBS` is now `ClassVar[int] = 24` —
  makes the class-attribute intent explicit instead of relying on
  Pydantic's implicit underscore handling.
- src/impulso/fitted.py: `FittedVAR.has_exog` drops `@computed_field`
  (now a plain `@property`) so it stops appearing in `model_dump()`.
- src/impulso/sv/dynamics.py: `RandomWalk.build_latent_path` /
  `AR1.build_latent_path` swap `Any` for `"pt.TensorVariable"` forward
  refs that match the SVDynamics Protocol declaration; drop the
  now-unused `Any` import.
- src/impulso/results.py: delete `VARResultBase.__repr__` override —
  Pydantic's default produces a useful compact repr because every
  `idata` field has `Field(repr=False)`.
- src/impulso/**/*.py: docstring sweep — double backticks (RST) → single
  backticks (Markdown / mkdocstrings); no more `:meth:` / `:class:`
  cross-refs (replaced with plain backticked names in earlier passes).
- CLAUDE.md: codify the docstring convention under "Code Conventions".
- src/impulso/identified.py: delete
  `forecast_error_variance_decomposition`; `fevd` is the canonical
  name. Docstring + .qmd / .md cross-references updated.
- pyproject.toml + uv.lock: bump `0.0.5 → 0.0.6` to ship the cumulative
  audit cleanup (#73 + #75 + #77 + this PR).

Closes audit findings #5, #8, #12, #13, #14, #15, #16
(reports/audit-2026-05-18.md).

Breaking (pre-v0.1): callers of
`IdentifiedVAR.forecast_error_variance_decomposition` must use
`IdentifiedVAR.fevd` (no signature change). The long name was always
an alias; per repo policy pre-v0.1 API breaks are in scope.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

This branch was previously deployed

1 inactive deployment
docs-preview — ddc56835 Deployed May 18, 2026 by thomaspinder via deploy-docs-preview #151
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Labelled DataFrames for IRF / FEVD / HD result accessors

2 participants