4.0.0 (2026-08-02)
tsam v4 is a rewrite of the internals: aggregation is now a chain of stateless functions in src/tsam/pipeline/, the class-based TimeSeriesAggregation API has been removed — tsam.aggregate() is the single entry point — and every internal identifier moved from camelCase to snake_case. For the overwhelming majority of configurations the results are bit-identical to 3.4.2; the exceptions are listed below and in the migration guide, which says for each change whether — and what — you need to do.
The v4 line was squash-merged as a single commit (#234); the entries below are reconstructed from the pull requests it contains.
⚠ BREAKING CHANGES
- the legacy
TimeSeriesAggregationAPI and the v3 compatibility shims have been removed — usetsam.aggregate()instead (#337, #338) - package structure reorganized (
utils/→algorithms/, newpipeline/, public serializers) (#338) - new pipeline architecture, weight decoupling, and snake_case API (#176)
- per-column
weightsare now a top-level argument ofaggregate();ClusterConfig(weights=...)raisesTypeError(#176) - cluster and segment representations are resolved independently — v3 silently discarded the cluster setting when both were set (#436)
- the duration representation preserves the integral and the min/max envelope (#376)
cluster_representatives,reconstructed, andoriginalreturn columns in input order instead of alphabetically sorted (#234)MinMaxMeannaming a column that is not in the data — or the same column in bothmin_columnsandmax_columns— now raisesValueErrorinstead of being silently ignored (#234)- review follow-ups on the v4 pipeline (#434)
Features
- new pipeline architecture (#234) (5d99d59)
- concurrency-preserving distribution ordering (#377, #400)
- type annotations for all functions in
src/tsam(#339, #402) - plot:
compare()gainedtime_sliceand a color dimension (#338) - plot: new cluster-representative plot (#412)
Bug Fixes
- result:
ClusteringResult.apply()is now faithful to the run it replays (#438) - algorithms: representative selection breaks ties deterministically (#439)
- pipeline: restore v3 parity for period sums (#436)
- representations: correct maxoid variable name and document its scope (#366, #419)
- docs: disable
navigation.instantso notebook plots render (#388)
Deprecations
result.plot.cluster_weights()is renamed toresult.plot.cluster_counts(); the old name still works and emits aFutureWarningDistribution(scope="cluster")is renamed toDistribution(scope="local");"cluster"is normalized and emits aFutureWarning(#378, #382, #383)
Documentation
- documentation restructured along Diátaxis (Tutorials / How-to / Explanation / Reference) (#412)
- v4 API reference and architecture docs (#331)
- docstrings normalized to Google style (#339, #379, #384, #416)
- terminology in docs and notebooks aligned with the glossary (#422)
- branding and logos unified across README and the RTD landing page (#433)
- tuning-notebook animation starts at full resolution (#421)