All notable changes to optica are documented here.
Breaking changes are marked Breaking and each carries a migration note.
The format follows Keep a Changelog. This project adheres to Semantic Versioning starting at 1.0; pre-1.0 minor releases may contain breaking changes.
#![cfg_attr(not(feature = "std"), no_std)]: the crate now builds withoutstd. Heap-using modules (data,grid,phase,prelude,spectrum) are gated behind theallocfeature;medium,ray,scatter,transportare always available.serdefeature: derivesSerialize/Deserializeon public data, error, and policy types (Provenance,DataSource,Axis,AxisDirection,ConstantRegion,OutOfRange,GridError,Interpolation,SpectrumError,MieParams,ScatterError,OpticalCoefficientError,PhaseError,IntegrationOpts,IntegrationMethod,TransportError).TableSourcederives onlySerialize(it borrows&'staticdata).medium::InverseLength<U>type alias (Per<Ratio, U>) for typed reciprocal lengths used by optical coefficients.medium::OpticalCoefficientErrorandOpticalCoefficients::try_new,HomogeneousMedium::try_new: fallible, validated constructors.phase::PhaseError, validatedHenyeyGreensteinPhaseFunction::try_newandDoubleHenyeyGreensteinPhaseFunction::try_new.scatter::ScatterError,MieParams::try_new,scatter::try_rayleigh_optical_depth_bodhaine99,scatter::try_mie_optical_depth.transport::IntegrationMethodenum (Midpoint,Trapezoidal,Simpson,GaussLegendre2,GaussLegendre4) andtransport::TransportError.IntegrationOptsnow carries amethodfield. Newtransport::try_integrate_optical_depthvalidates inputs.spectrum::SampledSpectrum:domain,contains,overlap_domain,resample_onto(typed, takes&[Quantity<X>]),resample_onto_raw(raw escape hatch),normalize_area(returnsSampledSpectrum<X, Ratio>),normalize_area_raw(raw escape hatch),normalize_peak(returnsSampledSpectrum<X, Ratio>),normalize_peak_raw(raw escape hatch),map_values_to(typed closure),map_values_raw(raw escape hatch),zip_with_to(typed closure),zip_with_raw(raw escape hatch).medium::TryMedium<C, F, U>trait for fallible/tabulated media.HomogeneousMedium::sigma_a()andsigma_s()typed getters returningQuantity<InverseLength<U>>.grid::Axis::bounds,Grid2D::x_bounds/y_bounds/domain,Grid3D::x_bounds/y_bounds/z_bounds/domain.spectrum::SpectrumError::InvalidValuevariant. Enum marked#[non_exhaustive].tests/serde_roundtrip.rs: JSON round-trip smoke tests for serialized types.
HomogeneousMedium::new,OpticalCoefficients::new,HenyeyGreensteinPhaseFunction { g: … }literal construction,DoubleHenyeyGreensteinPhaseFunction { … }literal construction,MieParams::new,rayleigh_optical_depth_bodhaine99, andmie_optical_depthare removed. Use the correspondingtry_new/try_*variants.PhaseModel::HenyeyGreenstein { g }enum variant is nowPhaseModel::HenyeyGreenstein(HenyeyGreensteinPhaseFunction); the wrapped function carries its own validated asymmetry parameter.- The fake unit markers
AbsorptionCoeff,ScatteringCoeff, andExtinctionCoeffare removed. Coefficients now use the real reciprocal-length unitInverseLength<U> = Per<Ratio, U>. IntegrationOpts { n_steps }literal construction must now supplymethod; useIntegrationOpts::default()orIntegrationOpts::new(n_steps, method).SpectrumErroris now#[non_exhaustive].HenyeyGreensteinPhaseFunction::try_newandDoubleHenyeyGreensteinPhaseFunction::try_newnow rejectg = ±1(open interval(-1, 1)strictly). The HG formula degenerates to a Dirac delta at those limits.SampledSpectrum::normalize_areareturnsSampledSpectrum<X, Ratio>(notSelf);normalize_peaklikewise.SampledSpectrum::map_valuesrenamed tomap_values_raw;zip_withrenamed tozip_with_raw;resample_onto(&[f64])renamed toresample_onto_raw.HomogeneousMediuminternal fields now stored asQuantity<InverseLength<U>>.
0.1.0 — 2026-05-26
Initial release preparation.
- Added the initial
opticacrate with typed grids, spectra, participating-media building blocks, phase functions, and transport helpers. grid::AxisDirectionis nowpuband re-exported from the crate root, enabling callers to name it without importing the internal module.grid::algomodule is nowpub. Exposes direction-aware kernels:validate_axis,linear_1d,bilinear,bilinear_unit,trilinear,trilinear_unit.grid::Grid1D::interp_at_with,Grid2D::interp_at_with,Grid3D::interp_at_with: fallible versions that accept a pre-validatedConstantRegionhint to skip re-validation.grid::Grid2D::from_raw_row_major_y_descending: constructor for grids whose y-axis runs high-to-low (e.g. Leinert zodiacal data), storing internally with a reflection transform so queries use the normal ascending convention.grid::GridError::NonUniformStep: new variant signalled when a uniform axis has a non-uniform step after construction.grid::ConstantRegionre-exported from crate root.- Three runnable examples under
examples/:spectrum_ascii,grid2d_interp,optical_depth. - GitHub CI workflow (
.github/workflows/ci.yml) and publish workflow (.github/workflows/publish.yml).
grid::Grid2Dstorage layout changed from x-major (values[ix*ny+iy]) to y-major (values[iy*nx+ix]) row-major order. Any code constructing aGrid2Dwith raw values or readingGrid2D::valuesdirectly must update the storage order.grid::Grid3Dstorage layout changed fromix*(ny*nz)+iy*nz+izto(iz*ny+iy)*nx+ix(z-outermost, y-middle, x-innermost). Same caveat applies.grid::GridErrorvariants renamed:OutOfBounds→OutOfRange;axisfield type changed fromusizeto&'static strfor clearer messages.lo/hifield names replacemin/max.grid::Axis::validate_for_axisnow takesname: &'static strinstead ofaxis: usize.data::Provenance::citednow takes a singlesource: &'static strargument (previously two arguments).