Releases: TaN-MM-Org/ramansep
Release list
ramansep 0.6.0: joint Bayesian map inversion with spatial priors, Voigt fitter
Completes the roadmap: the v0.6 item -- joint Bayesian inversion with spatial priors -- plus the Voigt fitter previously documented as out of scope.
Joint Bayesian map inversion (bayesian_map_inversion)
- The per-pixel GLS treats every pixel alone; physically, strain and doping fields vary smoothly on the pixel scale. That knowledge is made explicit as a Gaussian Markov random field prior (Rue & Held 2005) on both fields, independently weighted (
lam_strain,lam_density), and the joint MAP problem is solved exactly as one sparse linear system on the 4-neighbor pixel lattice with Neumann boundaries. - Exact per-pixel posterior sigmas on request; the dense inverse is refused above
max_denseunknowns rather than approximated silently. - Because the estimator is linear-Gaussian its behavior is provable, and the tests assert it instead of trusting it:
lam = 0reproducesMultiModeModel.invert's maps and sigmas to machine precision; a spatially constant noiseless truth is recovered exactly at everylam(the prior vanishes on constants); thelam -> infinitylimit equals the independently computed pooled precision-weighted GLS; posterior sigmas shrink monotonically withlam(adding a PSD precision term shrinks the covariance in the Loewner order) -- asserted pixel by pixel.
Voigt fitter (fit_voigt, voigt, VoigtFit)
- Voigt lineshape via the Faddeeva function
scipy.special.wofz, peak-height normalized, fitted by the same Levenberg-Marquardt loop asfit_lorentzianwith the analytic Jacobian built from w'(z) = 2i/sqrt(pi) - 2 z w(z). - Anchors: gamma = 0 is the Gaussian exactly (< 1e-14 pointwise -- an identity of the Faddeeva function); sigma -> 0 converges linearly to the Lorentzian of half-width gamma; the analytic Jacobian matches finite differences; noiseless lines are recovered to 1e-8 from automatic starting values.
Deliberate scope (designed out, with reasons -- see README)
- The smoothness weights are user-chosen regularization, not estimated hyperparameters: full hierarchical inference would need noise assumptions this package refuses to invent.
- No shipped coefficient values beyond the cited example sets; the stated prior graph rather than a tunable kernel zoo.
44 tests, Python 3.9/3.11/3.12/3.13. Install: pip install ramansep.
overdetermined multimode inversion with model checking
New module multimode: the (strain, density) inversion for any number of Raman modes.
MultiModeModel.invert: per-pixel generalized-least-squares (Gauss-Markov) inversion, weighting each mode by its shift uncertainty; vectorized over whole maps.-
- Per-pixel goodness-of-fit: the weighted residual sum of squares is chi-square with (m - 2) degrees of freedom when the two-cause model holds, so the p-value map flags pixels where strain and doping alone cannot explain the measured shifts - something no exactly determined two-mode inversion can detect.
-
compare_mode_sets: expected-precision comparison of candidate mode subsets before an experiment.
-
- Reduces exactly to the two-mode
SeparationModelcore at m = 2 (asserted to machine precision).
Also: scipy declared as an explicit dependency; README Status and Roadmap reconciled with the release history.
- Reduces exactly to the two-mode
ramansep 0.4.0: peak-fitting front end
This release ships the roadmap's front end. fit_two_modes takes a raw spectrum, fits a Lorentzian to each mode window with a NumPy-only Levenberg-Marquardt solver using analytic Jacobians, and returns the peak shifts and one-sigma uncertainties that SeparationModel.invert consumes. The test suite checks the Jacobian against finite differences, exact parameter recovery on noiseless lines, statistical compatibility of the reported center uncertainty with the actual scatter on seeded noisy lines, and a full spectrum-to-inversion round trip. The fitter is deliberately Lorentzian-only and says so; a Voigt treatment for instrument-dominated lines remains future work. The README gains a peak-fitting section and the roadmap now reflects what actually shipped in each version.
v0.3.0: graphene G+2D coefficient set
Adds graphene_g_2d_lee2012(): the G + 2D pair of monolayer graphene, expressing the vector decomposition of Lee, Ahn, Shim, Lee and Ryu, Nat. Commun. 3, 1024 (2012) as a linear inversion. Strain axis: -23.5 cm^-1 per percent of randomly oriented uniaxial strain with the measured 2D/G slope 2.2 +/- 0.2; hole-doping axis: the measured slope 0.70 +/- 0.05.
Unit honesty, on purpose: the doping output of this set is the G-band shift attributable to hole doping (cm^-1), not a carrier density. The graphene G-mode doping response is nonlinear and sign-dependent, so no universal linear per-density rate exists to ship; the docstring points to the gated calibrations (Froehlicher and Berciaud, Phys. Rev. B 91, 205413 (2015)) needed for a substrate-specific conversion.
Tests lock every constant to its source, verify the decomposition roundtrip exactly, verify that pure-strain and pure-doping trajectories decompose to zero of the other cause, and assert the noise amplification closed forms (the raw condition number of this set is an artifact of the mixed units; the docstring explains).
Install: pip install ramansep
v0.2.1: PyPI packaging release
Packaging release: complete PyPI metadata, CONTRIBUTING.md, JOSS paper draft, and a Trusted-Publishing workflow that tests, builds and publishes to PyPI on release. No changes to the physics code beyond the version number.
After this release: pip install ramansep
v0.2.0: cited MoS2 coefficient sets
Two cited coefficient sets for monolayer 1H-MoS2 ship with full provenance, and the test-suite reproduces the source paper's published separation results from them.
- mos2_a1_2la(): the A'1 + 2LA(M) pair of the source paper. Strain lever arms -5.1 and -20.9 cm^-1 per percent of biaxial strain (frozen-phonon DFT, ratio 4.1); A'1 doping coefficient -2.2 cm^-1 per 1e13 cm^-2 of electrons (Chakraborty et al., Phys. Rev. B 85, 161403(R) (2012)). The 2LA(M) doping coefficient is unmeasured and set to zero, with the source paper's 16% bound on the consequence documented.
- mos2_eprime_a1(): the all-optical E' + A'1 pair from the measured biaxial Grueneisen parameters of Michail et al., ACS Appl. Mater. Interfaces 16, 49602 (2024). For equal shift noise it returns about five times the strain uncertainty of the paper pair; included for comparison.
- New tests lock every number and reproduce the published results: edge charge 2.3e12 cm^-2 from a 0.5 cm^-1 A'1 redshift with 2LA(M) unmoved, and 0.134% interior tension carrying no significant charge. 13 tests total.
- FUNDING.yml added (Patreon sponsor button).
No API changes; v0.1 code continues to work unchanged.
v0.1.0
Initial release. Two-mode linear inversion separating strain from carrier density in 2D-material Raman maps, with uncertainty propagation (validated against Monte Carlo) and conditioning diagnostics. Ships no material constants by design: supply a ModeCoefficients with cited provenance. Test suite (6 tests) runs on CI.