What shipped in each release; why is in the dev diary, what is next in the roadmap.
v0.7.0 — 2026-08-17¶
The fitting subsystem, the domain-contract engine, a hardened vocabulary, and a documentation site rebuilt around them.
Breaking
The controlled vocabulary is canonical-only — no aliases. Bruker multi-receiver data now loads with the dimension
coil(waschannels), acquisition dimensions are singular (average,repetition), vocabulary terms are frozen against mutation, and the legacybruker_group_delayattribute fallback is gone. Rename inbound dimensions withobj.rename({...})untilda.xmr.map_vocablands. — #65 · #96 · The controlled vocabulary
Added
da.xmr.fit_amaresfits AMARES in the time domain and returns aDatasetof fitted parameters alongside the reconstructed signals. It meets data in either domain and returns it unchanged, normalises away the magnitude scale trap that made Bruker-scale FIDs “converge” on their prior, and writesNaNfor a failed voxel rather than a spurious zero.build_prior_knowledgereplaces pyAMARES’s positional CSV with a named-peak dict, and the optimizer itself lives behind the optionalxmris[fitting]extra, so a bareimport xmrisnever pulls it in. — #67 #69 #70 #80 #81 #82 · #105 · Quick start: fitting · AMARES in depth · diaryEvery domain-sensitive transform now declares the domain it works in, via
@computes_in(domain-preserving) or@ensures_domain(funnelling), so passing a FID where a spectrum is wanted converts instead of returning nonsense. — #42 #63 · #73 · #77 · #78 · The Two Domains · Domain contracts in actionxmris.set_options(auto_convert=False)turns that automatic conversion into a loud error naming the converter to call — strict mode for quantitative work. Global or a context manager, mirroringxr.set_options. — #63 · #79 · The Two Domainsda.xmr.baseline_alscorrects a spectral baseline by asymmetric least squares. — #43 · #44 · Baseline correctionda.xmr.estimate_group_delaymeasures a Bruker group delay from the data by minimising the residual, instead of trusting the header value. — #85 · #89 · Bruker — group delayda.xmr.widget.scroll_spectrascrolls through a stack of spectra, andda.xmr.widget.apodizetunes line broadening against a live plot. Both render in the built documentation, not only in a running kernel. — #16 · #37 · #38 · #40 · Interactive scrolling · Interactive apodization
Changed
xmrisis released under BSD-3-Clause, replacing AGPL-3.0. — #130autophasewas rewritten for robustness, andnmrglueis no longer a dependency. — #30 · #36 · Automated phase correctionPlotting is configured by objects rather than keyword soup —
WaterfallConfig,CarpetConfig,PlotTrajectoryConfig,PlotQCGridConfig, reached throughda.xmr.plot. — #39 · #41 · Config-based plotting · Waterfall plots · Carpet plotsapodize_exp,apodize_lgandzero_fillreturn the representation you handed them, whilebaseline_alsfunnels into the spectral domain and stays there. — #63 · #78 · The Two Domains
Fixed
A bare
pip install xmriswas unimportable: matplotlib is imported by everyimport xmrisbut arrived only transitively through pyAMARES, and vanished when pyAMARES moved to thefittingextra.requires-pythonalso read<=3.13, which PEP 440 resolves to<= 3.13.0— admitting no 3.13 patch release. Both are fixed, and CI now installs the way a user does. — #122 · #147fit_amaresreads the canonicalreference_frequencyattribute, so FIDs produced bysimulate_fidfit without a manualmhz=. — #68 · #93Waterfall and carpet plots reject complex input instead of silently plotting its real part, and keep the time axis’s units. — #83 · #94
import xmrisno longer emits aDeprecationWarning. — #67 · #92
Documentation
The site was rebuilt: one directory per chapter, hands-on tutorials split from concept explainers, and a landing page per chapter. — #126 #137 · #139
The contributor documentation is new in full: The Architecture Contract — the eleven rules every change to
src/xmris/obeys — a page per kind of contribution, and the dev diary. — #72 · #103 · #114 · Contribute · Open a pull request · diaryTwo explainers for the design decisions users hit first: The Two Domains on why a function cares whether it is handed a FID or a spectrum, and The controlled vocabulary on why the names are fixed. — #76 · #100
The roadmap says what is shipped, in motion, and still being argued about. — #116 · #123 · #145
Every pull request now publishes a fully executed preview of the site it would produce. — #112 · How the documentation reaches the web · diary
Maintenance
The documentation pages are the maths tests — every tutorial and explainer is executed by
nbmakeon both ends of the supported Python range, and a whole-tree docs-style checker gates the merge. — #104 · #110 · diarySeven dependency updates, now arriving weekly via Dependabot, plus CI hardening: the site is published from workflow artifacts rather than a 103 MB committed branch, the Codecov uploader comes from PyPI so an outage cannot block every merge, and
ruff formatis gated for the first time. — #115 #141 #151 · #142 · #146 · #152
Earlier releases¶
v0.1.0 – v0.6.1 predate this changelog. Their contents are the tag list and the commits between them.