Skip to content

Add TopiaryResult wrapper with provenance tracking#112

Merged
iskandr merged 3 commits into
masterfrom
topiary-result
Apr 12, 2026
Merged

Add TopiaryResult wrapper with provenance tracking#112
iskandr merged 3 commits into
masterfrom
topiary-result

Conversation

@iskandr

@iskandr iskandr commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds TopiaryResult — a wrapper that bundles a predictions DataFrame with its metadata (model versions, source files, form, filter/sort history) — plus a concat() function for merging results with provenance preserved across the merge.

  • Delegates common DataFrame operations so existing code that treats results as DataFrames keeps working
  • read_tsv / read_csv return TopiaryResult (breaking: was (df, Metadata))
  • Auto-populates a source column and Metadata.sources from the filename (overridable via tag=)
  • concat([r1, r2]) merges model maps (warns on version conflicts), concatenates sources, preserves filter/sort only if all inputs agree, raises on mixed forms
  • Added to_expr_string() / to_ast_string() to legacy filter classes as a stopgap (see DSL refactor: unify filter leaves + vectorize eval #111 for the full DSL refactor that removes them)

Bumps to 4.12.0. 760 tests pass.

See #109 for the wrapper design. Follow-on DSL cleanup in #111.

Test plan

  • 34 new tests in test_result.py cover construction, delegation, form conversion, serialization, loader source-tracking, concat semantics (basic, sources-merged, models-union, version-conflict-warns, mixed-forms-raises, empty, single, roundtrip)
  • Existing IO tests migrated to new return type
  • Full suite: 760 tests pass locally
  • CI green on Python 3.10, 3.11, 3.12

iskandr added 3 commits April 12, 2026 13:10
TopiaryResult bundles a predictions DataFrame with its metadata —
model versions, source files, form (long/wide), filter/sort history —
so that provenance survives through transformations and
serialization round-trips.

**TopiaryResult (topiary/result.py, new):**
- Fields live directly on the result (no .metadata indirection):
  topiary_version, form, models, sources, filter_by_str/ast,
  sort_by_str/ast, extra. Plus `.metadata` compat property.
- Delegates DataFrame operations (__len__, __iter__, __getitem__,
  __contains__, columns, shape, empty, head, tail, iterrows,
  itertuples) so existing DataFrame-style code keeps working.
- `to_wide()` / `to_long()` — form conversion preserves metadata.
- `to_tsv()` / `to_csv()` — writes comment-block metadata.
- Construction: TopiaryResult(df, **kwargs) or TopiaryResult(df, metadata).

**concat():**
- Merges TopiaryResults, unioning models (warns on version conflicts),
  concatenating sources, preserving filter/sort only if all inputs agree.
- Raises on mixed forms (long + wide).

**IO provenance (topiary/io.py):**
- Metadata gains `sources: list[str]` field; multiple #source= lines
  in the comment block.
- read_tsv/read_csv return TopiaryResult (breaking change).
- Both accept optional `tag=` to label the rows; defaults to filename.
- Auto-populates a `source` column on the DataFrame if not present.

**Legacy filter stringification (will be replaced by #111):**
- EpitopeFilter/ColumnFilter/ExprFilter/RankingStrategy gained
  to_expr_string() producing parseable DSL syntax and to_ast_string()
  producing canonical structural form. These will be removed when the
  DSL refactor lands (see #111).

**README/pyproject:**
- Description updated: "Predict, filter, and rank MHC-presented
  peptides from any antigen source"
- Removed obsolete mhctools version requirement line.

Bump to 4.12.0 (breaking: read_tsv/read_csv return TopiaryResult
instead of (df, Metadata) tuple).

See #109 for the full wrapper design discussion and #111 for the
follow-on DSL refactor.
- Add 26 tests for filter_by() and sort_by() covering string and DSL
  object inputs, history recording (AND for filter, replace for sort),
  empty-df noop, metadata preservation, TSV round-trip, and immutability.
- Add 5 tests for concat()'s history-drop warning behavior.
- concat() now warns via UserWarning when filter_by or sort_by metadata
  is discarded because inputs disagree.
- Collapse duplicate .metadata / _as_metadata() into one public
  .metadata property.
- Document pandas semantics of __contains__ / __iter__ in the class
  docstring (membership checks columns not rows; iteration yields
  column names).
- Tighten filter_by_ast / sort_by_ast docstrings to describe the current
  types and the & contract.
- Add CHANGELOG entry for 4.12.0 breaking read_tsv/read_csv return type.
In CI environments without mhcflurry package/model files, mhctools
does not expose MHCflurry via inspect.getmembers. Skip rather than
fail so the test is a no-op when the dependency is unavailable.
@iskandr iskandr merged commit 141e56e into master Apr 12, 2026
8 checks passed
@coveralls

Copy link
Copy Markdown

Coverage Status

coverage: 84.431% (-2.9%) from 87.363% — topiary-result into master

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.

2 participants