What’s New in Revision 0.12.5

These are the changes in SpectroChemPy-0.12.5. See Release notes for a full changelog, including other versions of SpectroChemPy.

New Features

  • Add scp.migrate_legacy_file() for explicit migration of legacy SCP/PSCP files to the safe raw-base64 format. Legacy files with pickle-based payloads can be converted safely with an explicit trust acknowledgement (allow_unsafe_legacy=True). The source file is never modified or deleted.

  • Add seed parameter to scp.random() and scp.normal(). The parameter is forwarded to numpy.random.default_rng, making it possible to obtain reproducible random numbers in scripts and gallery examples.

Bug Fixes

  • Fix FFT frequency-coordinate generation (PR #1563). FTIR interferogram FFT results now use a positive descending wavenumber axis from the highest retained rfft bin toward zero, so the documented 400–4000 cm^-1 window again contains the calculated spectra. Generic FFT coordinates now follow the fftshift(fftfreq) order used by the transformed data, while NMR plugin FFT post-processing remains unchanged.

  • Consolidate Sphinx-Gallery structure and rendering (PR #1564, PR #1565). Plugin examples are now staged once in canonical scientific sections, thumbnail directives are placed before module docstrings to avoid empty cells, and stale top-level plugin examples were removed.

  • Fix MSCTransformer.inverse_transform() so it no longer reuses fit-dataset diagnostic coefficients positionally for independently transformed datasets. MSCTransformer now documents a_ and b_ as fit-dataset diagnostics, preserves explicit masked references, computes MSC regressions from the effective paired masks, and reuses the learned reference only with compatible spectral geometry, including feature count, spectral dimension name, coordinate order and coordinate units when present.

  • Fix sample-local preprocessing transformers so SNVTransformer and NormalizeTransformer(dim="x") compute per-spectrum statistics on the dataset being transformed instead of reusing training spectra positionally. Their inverse_transform() now raises an explicit error for these sample-local modes because the required per-observation factors are not learned reusable state. This is an intentional behavior break from the previous unsafe inverse, which could only work by reusing training or last-transform state positionally.

  • Fix dim keyword argument in Savitzky-Golay, smoothing and Whittaker filters (#1091). savgol(), smooth(), whittaker() and Filter(...).transform() now accept a dim parameter to select the processing axis. Dimension names (e.g. "x") and integer indices are resolved via the standard dimension selection mechanism. Invalid types (bool, tuple, list) and unknown names raise TypeError or ValueError.

  • Savitzky-Golay derivatives now automatically use the signed spacing of a uniformly spaced coordinate when delta is omitted (#1091). For deriv > 0, the savgol() wrapper detects the coordinate along the processed axis and derives a signed delta. An ascending coordinate yields a positive delta, a descending one yields a negative delta. The derivative sign therefore conforms to the physical variable carried by the coordinate without relying on the unit-based _reversed heuristic. An explicit delta has priority and disables auto-detection. On a non-uniform or missing coordinate a warning is emitted and the index-based delta=1.0 is used as a fallback. deriv=0 is unchanged.

  • Fix sign of Savitzky-Golay derivatives when an explicit delta is provided with cm⁻¹ or ppm coordinates (#1552). The former _reversed correction applied (-1)**deriv on the Savitzky-Golay path when the coordinate carried cm⁻¹ or ppm units, flipping the sign of odd-order derivatives on ascending coordinates. An explicit delta is now passed to SciPy with its sign; no unit-based correction is applied. For a descending coordinate, supply a negative delta if the derivative should follow the physical axis. This is a numeric correction for affected calls with odd-order derivatives.

  • Savitzky-Golay derivative units are now propagated for physically scaled paths. A derivative of order n carries source_units / coordinate_units**n when the delta is derived from a uniform coordinate or explicitly provided while the coordinate has units. Smoothing (deriv=0) and index-based fallbacks preserve the source units unchanged. This is a scientific correction observable for datasets with physical units.

Breaking Changes

  • MSCTransformer.inverse_transform() now raises an explicit error. The previous behavior could appear to restore the result of fit_transform() on the same dataset, but it reused training coefficients positionally and was unsafe for datasets transformed later.

    Migration: if you need to reverse MSC, apply the stored a_ and b_ coefficients manually or refit on the target dataset. Most workflows only need the forward-corrected spectra and do not require an inverse.

  • msc() and MSCTransformer now raise when a spectrum has zero local slope relative to the reference. The previous b_safe fallback produced a zero-valued corrected spectrum, hiding an invalid MSC regression.

    Migration: verify that reference and sample spectra contain spectral variation (non-constant values) before calling msc(). Constant or degenerate spectra are invalid MSC inputs.