Spectrum1D
#
Spectrum1D(
frequencies: FloatArray | None = None,
amplitudes: ComplexArray | None = None,
frequency_unit: FrequencyUnit = HERTZ,
reference_frequency_hz: float | None = None,
metadata: dict[str, str] | None = None,
)
1D frequency-domain spectrum.
Attributes:
| Name | Type | Description |
|---|---|---|
frequencies |
FloatNdArray
|
Frequency coordinates |
amplitudes |
ComplexNdArray
|
Complex amplitudes |
frequency_unit |
Unit of frequency coordinates |
|
reference_frequency_hz |
Reference frequency for PPM calculations |
|
metadata |
dict[str, str]
|
Optional metadata dictionary |
processing_history
class-attribute
instance-attribute
#
processing_history: ProcessingHistory | None = (
betterproto2.field(
6, betterproto2.TYPE_MESSAGE, optional=True
)
)
Processing history - read-only audit log of all operations applied to this spectrum
metadata
class-attribute
instance-attribute
#
metadata: dict[str, str] = betterproto2.field(
4,
betterproto2.TYPE_MAP,
map_meta=betterproto2.map_meta(
betterproto2.TYPE_STRING, betterproto2.TYPE_STRING
),
)
Optional metadata
_frequency_axis
class-attribute
instance-attribute
#
Exactly one frequency axis (enforced by validation)
_amplitudes
class-attribute
instance-attribute
#
_amplitudes: NdComplexArray | None = betterproto2.field(
2, betterproto2.TYPE_MESSAGE, optional=True
)
1D complex amplitude data (shape = [N])
solvent_reference_ppm
class-attribute
instance-attribute
#
solvent_reference_ppm: float | None = betterproto2.field(
5, betterproto2.TYPE_FLOAT, optional=True
)
Solvent reference PPM for calibration (set from sample's solvent info)
visualization_handler
property
writable
#
Plugin visualization handler ID (e.g., 'nanalysis:cosy_2d').
frequencies
instance-attribute
#
amplitudes
instance-attribute
#
frequency_range_hz
property
#
Frequency range of the spectrum in Hz.
_init_history
#
Initialize the processing history.
Called from init of Signal1D/Spectrum1D. Always creates a ProcessingHistory instance - history is always enabled.
_record_history_entry
#
_record_history_entry(
operation: str,
parameters: dict[str, str],
shape_before: tuple[int, ...],
shape_after: tuple[int, ...],
source: str = "tqt_nmr",
) -> None
_copy_history_to
#
Copy processing history to another object.
Used by copy() methods to preserve history lineage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
Self
|
Object to copy history to. |
required |
_axis_ppm
#
The frequency axis in PPM, whatever unit it is stored in.
A spectrum converted for display already holds PPM; anything else is baseband offset from the carrier and needs the reference frequency.
suppress_region
#
suppress_region(
center: float,
width: float,
method: SuppressionMethod = SUPPRESS_INTERPOLATE,
) -> Self
Suppress a spectral region in-place.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
center
|
float
|
Center of the region to suppress (in spectrum frequency units). |
required |
width
|
float
|
Full width of the region to suppress (in spectrum frequency units). |
required |
method
|
SuppressionMethod
|
Suppression method enum. |
SUPPRESS_INTERPOLATE
|
Returns:
| Type | Description |
|---|---|
Self
|
Self (mutated in-place) for method chaining. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the region is entirely outside the spectrum range. |
suppress_solvent_line
#
suppress_solvent_line(
expected_ppm: float,
search_window_ppm: float = DEFAULT_SOLVENT_SEARCH_WINDOW_PPM,
) -> SolventLineFit | None
Subtract the fitted lineshape of the solvent line near a known shift.
Only the fitted solvent component is removed; any other signal in the same region, including signal underneath the solvent, is left in place. Calling this a second time on the same spectrum removes nothing further.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
expected_ppm
|
float
|
The shift the sample's solvent predicts for the observed nucleus, in ppm. |
required |
search_window_ppm
|
float
|
PPM searched either side of |
DEFAULT_SOLVENT_SEARCH_WINDOW_PPM
|
Returns:
| Type | Description |
|---|---|
SolventLineFit | None
|
The component that was subtracted, or None when no solvent line was |
SolventLineFit | None
|
found or the spectrum was already suppressed. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the spectrum has no reference frequency, so no ppm position can be located on its axis. |
reference_to_solvent
#
reference_to_solvent(
solvent: PredefinedSolvent,
nucleus: Nucleus | None = None,
search_window_ppm: float = 0.5,
) -> Self
Reference spectrum to a known solvent peak.
Finds the tallest peak within search_window_ppm of the expected solvent position and shifts the spectrum so that peak is at the correct PPM.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
solvent
|
PredefinedSolvent
|
Predefined solvent enum value |
required |
nucleus
|
Nucleus | None
|
Target nucleus (defaults to 1H) |
None
|
search_window_ppm
|
float
|
PPM range to search for solvent peak |
0.5
|
Returns:
| Type | Description |
|---|---|
Self
|
Self with shifted frequencies |
Raises:
| Type | Description |
|---|---|
ValueError
|
If solvent/nucleus combination not found or no peak in window |
reference_to_ppm
#
reference_to_ppm(
target_ppm: float,
search_window_ppm: float = 0.5,
use_centroid: bool = False,
) -> Self
Shift spectrum so the tallest peak near target is at target_ppm.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_ppm
|
float
|
The PPM value where the peak should be placed |
required |
search_window_ppm
|
float
|
PPM range around target to search for peak |
0.5
|
use_centroid
|
bool
|
If True, use weighted centroid instead of maximum |
False
|
Returns:
| Type | Description |
|---|---|
Self
|
Self with shifted frequencies |
Raises:
| Type | Description |
|---|---|
ValueError
|
If reference_frequency_hz is not set or no peak found |
reference_manual
#
Manually reference spectrum by specifying current and target PPM.
This is for UI-driven referencing where user clicks on a peak and specifies what PPM it should be shifted to.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
click_ppm
|
float
|
The current PPM value of the clicked position |
required |
target_ppm
|
float
|
The PPM value it should be shifted to |
required |
Returns:
| Type | Description |
|---|---|
Self
|
Self with shifted frequencies |
Raises:
| Type | Description |
|---|---|
ValueError
|
If reference_frequency_hz is not set |
align_by_correlation
#
align_by_correlation(reference: Spectrum1D) -> Self
Align this spectrum to a reference using cross-correlation.
Computes the lag that maximizes the cross-correlation between the magnitude spectra, then shifts the frequency axis by that amount.
Both spectra must use the same frequency spacing (same number of points over the same spectral width). The reference spectrum is not modified.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
reference
|
Spectrum1D
|
Reference spectrum to align to. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
Self with shifted frequencies. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the spectra have different lengths. |
_shift_in_axis_unit
#
Convert a PPM shift into the unit the frequency axis is stored in.
apply_harmonics_mask
#
Masks out harmonics by a cosine wave.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frequency_hz
|
float
|
Frequency of the harmonics to mask. |
50
|
k
|
float
|
Cutoff threshold of the cosine wave (higher = thinner mask). Defaults to 0.99. |
0.99
|
remove_peak
#
Zero-out a small window around peak_frequency_hz.
halves_symmetry_score
#
Compute a simple symmetry score of |z| around central_frequency_hz.
1.0 is perfectly symmetric; 0.0 very asymmetric.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
central_frequency_hz
|
float
|
Central frequency to split the spectrum with. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
float |
float
|
Inverse cosine distance. The lower the score the higher the spectrum's symmetry rate. |
find_peaks
#
find_peaks(
min_distance_hz: float | None = None,
min_height_ratio: float = 0.05,
prominence: float | None = None,
use_magnitude: bool = False,
adaptive: bool = False,
snr_threshold: float = 5.0,
mode: Literal["ml", "deconv"] = "ml",
ml_threshold: float | None = None,
) -> list[PeakInfo]
Find peaks in spectrum with advanced filtering.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_distance_hz
|
float | None
|
Minimum peak distance (in Hz). If None, auto ~1% span. |
None
|
min_height_ratio
|
float
|
Minimum peak height as a ratio of the maximum height (0-1). IGNORED ENTIRELY when adaptive=True, which takes no parameters at all. |
0.05
|
prominence
|
float | None
|
Minimum prominence as a ratio of the maximum height (0-1). When adaptive=False this defaults to None, meaning NO prominence filter is applied at all and every local maximum above min_height_ratio is reported. IGNORED when adaptive=True. |
None
|
use_magnitude
|
bool
|
If True, work on |z| else on Re(z). |
False
|
adaptive
|
bool
|
If True, run AUTO MODE: a statistically calibrated threshold
pass followed by Richardson-Lucy deconvolution against the
measured lineshape (see
:func: |
False
|
snr_threshold
|
float
|
DEPRECATED and ignored. |
5.0
|
mode
|
Literal['ml', 'deconv']
|
Which detector auto mode runs. Only meaningful with
|
'ml'
|
ml_threshold
|
float | None
|
The learned detector's operating point. Lower favours
recall, higher favours precision. None uses the model's own
default. Ignored unless |
None
|
analyze_multiplet
#
analyze_multiplet(
center_frequency: float | None = None,
search_width: float = 50.0,
min_height_ratio: float = 0.1,
method: Literal[
"structure", "fast", "pascal", "deconvolution"
] = "structure",
bootstrap_iterations: int | Literal["auto"] = "auto",
bic_threshold: float = 15.0,
peaks: list[PeakInfo] | None = None,
) -> MultipletAnalysis
Analyze peaks in a region to identify multiplet pattern and J-coupling.
Patterns reported: s, d, t, q, quint, sext,
sept, the compound patterns (dd, dt, dq, ...), and
m for a complex or unresolved multiplet.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
center_frequency
|
float | None
|
Center of the search region (in spectrum units). If None and peaks provided, calculated from peaks. |
None
|
search_width
|
float
|
Width of search region on each side of center. |
50.0
|
min_height_ratio
|
float
|
Minimum peak height as ratio of tallest peak in region. |
0.1
|
method
|
Literal['structure', 'fast', 'pascal', 'deconvolution']
|
Analysis method: "structure" (default), "deconvolution", or "fast" (alias "pascal"). |
'structure'
|
bootstrap_iterations
|
int | Literal['auto']
|
Number of bootstrap iterations for uncertainty estimation. Use "auto" for SNR-adaptive (default: SNR > 100 uses analytical, SNR 30-100 uses 50 iterations, SNR < 30 uses 200). |
'auto'
|
bic_threshold
|
float
|
BIC improvement threshold for peak count selection. |
15.0
|
peaks
|
list[PeakInfo] | None
|
Pre-detected peaks to use instead of re-detecting. When provided, the "fast" method uses these directly. For "structure"/"deconvolution", center_frequency and search_width are derived from peaks if not specified. |
None
|
Returns:
| Type | Description |
|---|---|
MultipletAnalysis
|
MultipletAnalysis with pattern, coupling constants, and confidence. |
MultipletAnalysis
|
For deconvolution/structure methods, includes uncertainties and fit metrics. |
analyze_multiplet_groups
#
analyze_multiplet_groups(
linkage_method: Literal[
"single", "average", "complete", "ward"
] = "single",
method: Literal[
"structure", "fast", "pascal", "deconvolution"
] = "structure",
peaks: list[PeakInfo] | None = None,
infer_missing_lines: bool = False,
) -> MultipletGroupsAnalysis
Detect and analyze all multiplet groups in the spectrum.
Peaks come from AUTO-MODE detection (:meth:find_peaks with
adaptive=True), which measures its own threshold from the trace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
linkage_method
|
Literal['single', 'average', 'complete', 'ward']
|
Hierarchical clustering linkage method ('single', 'average', 'complete', 'ward'). Default: 'single'. |
'single'
|
method
|
Literal['structure', 'fast', 'pascal', 'deconvolution']
|
Analysis method for pattern classification within each group: - "structure" (default): constrained J-pattern fit of the group's region, seeded by the group's peaks; reports J uncertainties. - "fast" (alias: "pascal"): position-only classification, no spectral fit. Cheap; use when the peak list is already reliable. - "deconvolution": peak-count selection, then the same constrained fit. |
'structure'
|
peaks
|
list[PeakInfo] | None
|
The lines to group and classify. Pass an already-detected (and possibly user-edited) peak list here to have grouping see exactly that list. Default (None) runs auto-mode detection. |
None
|
infer_missing_lines
|
bool
|
Allow a group to gain a line the detector did
not pick, when the observed intensities are better explained by
a pattern with one terminal line unobserved AND the trace holds
the predicted intensity there. Off by default: an inferred line
is a conclusion, not a measurement. Inferred lines are marked
|
False
|
Returns:
| Type | Description |
|---|---|
MultipletGroupsAnalysis
|
MultipletGroupsAnalysis with all detected groups. |
_infer_group_line
#
_infer_group_line(
group: MultipletGroup,
all_peaks: list[PeakInfo],
frequencies_hz: ndarray,
amplitudes: ndarray,
median_linewidth: float | None,
detection_floor: float,
enabled: bool,
collect_into: list[PeakInfo] | None = None,
) -> list[PeakInfo]
A line this group's intensities demand but no detector picked, if any.
Returns a list of at most one so the caller stays branch-free; empty when the feature is off or the evidence did not justify a line.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group
|
MultipletGroup
|
The group to complete. |
required |
all_peaks
|
list[PeakInfo]
|
Every detected line in the spectrum. Offered as neighbours in full, not just this group's: a line outside the group still puts its tail on the candidate position, and subtracting only the group's own lines reads an adjacent multiplet's flank as confirmation. |
required |
frequencies_hz
|
ndarray
|
Spectrum frequency axis, Hz. |
required |
amplitudes
|
ndarray
|
Real trace on that axis. |
required |
median_linewidth
|
float | None
|
Fallback FWHM when this group's own lines report none, Hz. |
required |
detection_floor
|
float
|
The detector's own height gate. |
required |
enabled
|
bool
|
Whether inference was asked for at all. |
required |
collect_into
|
list[PeakInfo] | None
|
Appended to with whatever is found, so the caller can gather every group's inferred lines without a separate step. |
None
|
_analyze_multiplet_deconvolution
#
_analyze_multiplet_deconvolution(
center_frequency: float,
search_width: float = 50.0,
min_height_ratio: float = 0.1,
bootstrap_iterations: int | Literal["auto"] = 200,
bic_threshold: float = 15.0,
) -> MultipletAnalysis
Analyze multiplet using deconvolution with BIC model selection.
_analyze_multiplet_structure
#
_analyze_multiplet_structure(
center_frequency: float,
search_width: float = 50.0,
bootstrap_iterations: int | Literal["auto"] = "auto",
) -> MultipletAnalysis
Analyze multiplet using structure deconvolution with CWT detection.
integrate_peaks
#
integrate_peaks(
peaks: list[PeakInfo],
integration_width: float | None = None,
normalize_to: int
| Literal["largest", "smallest"]
| None = None,
use_magnitude: bool = False,
width_multiplier: float = DEFAULT_INTEGRATION_HWHM_MULTIPLIER,
) -> list[IntegrationResult]
Calculate integrated areas for detected peaks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
peaks
|
list[PeakInfo]
|
List of peaks to integrate (from find_peaks()) |
required |
integration_width
|
float | None
|
Width of integration region on each side of peak (in spectrum units).
If None, auto-calculates from the peak's half-width at half-height
times |
None
|
normalize_to
|
int | Literal['largest', 'smallest'] | None
|
Index of peak to normalize to 1.00. If None, no normalization. |
None
|
use_magnitude
|
bool
|
If True, integrate |z|, else integrate Re(z). |
False
|
width_multiplier
|
float
|
Integration half-window in multiples of the peak's HWHM. A Lorentzian carries a heavy tail, so a narrow window introduces a systematic, linewidth-dependent quantitation bias: +/-1 HWHM captures 50% of the area, +/-20 (the default) ~97%. Reduce only for crowded spectra where neighbouring peaks would overlap the window. |
DEFAULT_INTEGRATION_HWHM_MULTIPLIER
|
Returns:
| Type | Description |
|---|---|
list[IntegrationResult]
|
List of IntegrationResult with area and bounds for each peak. |
integrate_shifts
#
integrate_shifts(
peaks: list[PeakInfo],
normalize_to: int
| Literal["largest", "smallest"]
| None = "largest",
use_magnitude: bool = False,
group_tolerance_hz: float = 20.0,
) -> list[ShiftIntegrationResult]
Integrate chemical shifts (multiplet groups) rather than individual peaks.
Groups peaks by their group_id (from multiplet analysis) or by proximity, then integrates the full region spanning each group. Uses integrate_peaks internally and sums per-peak areas within each group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
peaks
|
list[PeakInfo]
|
List of peaks (from find_peaks(), ideally with group_id set) |
required |
normalize_to
|
int | Literal['largest', 'smallest'] | None
|
Which group to normalize to 1.00. |
'largest'
|
use_magnitude
|
bool
|
If True, integrate |z|, else integrate Re(z). |
False
|
group_tolerance_hz
|
float
|
If peaks lack group_id, group by proximity (Hz). |
20.0
|
Returns:
| Type | Description |
|---|---|
list[ShiftIntegrationResult]
|
List of ShiftIntegrationResult, one per chemical shift group. |
deconvolve_region
#
deconvolve_region(
f_min: float,
f_max: float,
n_peaks: int | None = None,
bootstrap_iterations: int = 200,
) -> DeconvolutionResult
Full peak deconvolution for a spectral region.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f_min
|
float
|
Minimum frequency (Hz) |
required |
f_max
|
float
|
Maximum frequency (Hz) |
required |
n_peaks
|
int | None
|
Number of peaks to fit (auto-detect if None) |
None
|
bootstrap_iterations
|
int
|
Bootstrap iterations for uncertainty |
200
|
Returns:
| Type | Description |
|---|---|
DeconvolutionResult
|
DeconvolutionResult with fitted peaks and uncertainties |
estimate_snr
#
Estimate signal-to-noise ratio of the spectrum.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signal_region
|
tuple[float, float] | None
|
Optional (f_min, f_max) to restrict signal calculation. If None, uses entire spectrum. |
None
|
Returns:
| Type | Description |
|---|---|
float
|
Signal-to-noise ratio (linear scale) |
_peak_infos_from_indices
#
_peak_infos_from_indices(
x: ndarray,
y: ndarray,
idxs: ndarray,
fallback_linewidth_hz: float | None = None,
) -> list[PeakInfo]
Wrap detected sample indices as PeakInfo, with prominence and FWHM.
correct_baseline
#
correct_baseline(
method: BaselineMethod1D = "arpls",
edge_fraction: float = 0.1,
poly_order: int = 1,
smoothness_decades: float = 10.0,
asymmetry: float = 0.001,
iterations: int = 50,
tol: float = 0.001,
mask_sigma: float = 3.0,
als_lambda: float = 100000.0,
als_p: float = 0.01,
als_iterations: int = 10,
valley_prominence: float = 0.02,
valley_preserve_integral: bool = False,
valley_clip_negative: bool = False,
imaginary_method: ImaginaryBaselineMethod = "auto",
allow_unsafe_poly_order: bool = False,
**kwargs,
) -> Self
Apply baseline correction to the absorption channel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method
|
BaselineMethod1D
|
Baseline correction method:
- "arpls" (default): asymmetrically reweighted penalised least squares,
restricted to a signal-free mask and fitted on an extrapolated
extension of the trace.
- "airpls": adaptive iteratively reweighted penalised least squares.
Tends to inflate peak amplitudes; prefer "arpls".
- "asls": asymmetric least squares with |
'arpls'
|
edge_fraction
|
float
|
Fraction of each spectrum edge used by the edge-anchored methods ("edge", "median", "polynomial"). |
0.1
|
poly_order
|
int
|
Polynomial order for "polynomial" and "masked_poly". |
1
|
smoothness_decades
|
float
|
Whittaker smoothness as log10(lambda) quoted at 16384
points; the applied lambda is scaled by |
10.0
|
asymmetry
|
float
|
Asymmetry parameter |
0.001
|
iterations
|
int
|
Maximum reweighting iterations for the Whittaker methods. |
50
|
tol
|
float
|
Relative convergence tolerance for the Whittaker methods. |
0.001
|
mask_sigma
|
float
|
Signal-mask threshold in robust noise sigma; points with
|
3.0
|
als_lambda
|
float
|
Smoothness parameter for "als", quoted at 16384 points and
scaled by |
100000.0
|
als_p
|
float
|
Asymmetry parameter for "als". |
0.01
|
als_iterations
|
int
|
Iteration count for "als"; must be >= 1. |
10
|
valley_prominence
|
float
|
Minimum valley prominence as a fraction of max|y|. |
0.02
|
valley_preserve_integral
|
bool
|
Rescale the corrected spectrum so its integral matches the input integral. The scale factor is unbounded when the corrected integral is small, so quantitative work must leave this off. |
False
|
valley_clip_negative
|
bool
|
Clamp negative values to zero before rescaling. Clipping makes the residual noise one-sided instead of zero-mean, which invalidates downstream noise/SNR estimates and biases integrals upward. |
False
|
imaginary_method
|
ImaginaryBaselineMethod
|
How to baseline-correct the dispersion (imaginary) channel: - "auto" (default): apply the same constant offset for the "edge" and "median" methods, and leave the dispersion channel untouched for every other method. Only a constant offset is well defined on a bipolar lineshape; anything else rotates the spectrum's phase. - "same": apply the absorption-channel method to the imaginary part. - "polynomial": use the edge-anchored polynomial fit. - "none": leave the imaginary part untouched. |
'auto'
|
allow_unsafe_poly_order
|
bool
|
Permit |
False
|
**kwargs
|
Additional parameters (ignored for compatibility) |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
Self |
Raises:
| Type | Description |
|---|---|
ProcessingParameterError
|
If |
correct_phase_auto
#
correct_phase_auto(
method: Literal["acme", "peak_minima"] = "acme",
peak_width: int = 100,
return_phases: Literal[False] = False,
verbose: bool = False,
multi_start: bool | None = None,
p0_starts: Sequence[float] | None = None,
p1_starts: Sequence[float] | None = None,
strategy: Literal["seeded", "multistart"] = "seeded",
order: Literal["auto", 1, 2] | None = None,
) -> Self
correct_phase_auto(
method: Literal["acme", "peak_minima"] = "acme",
peak_width: int = 100,
return_phases: Literal[True] = True,
verbose: bool = False,
multi_start: bool | None = None,
p0_starts: Sequence[float] | None = None,
p1_starts: Sequence[float] | None = None,
strategy: Literal["seeded", "multistart"] = "seeded",
order: Literal["auto", 1, 2] | None = None,
) -> tuple[Self, tuple[float, ...]]
correct_phase_auto(
method: Literal["acme", "peak_minima"] = "acme",
peak_width: int = 100,
return_phases: bool = False,
verbose: bool = False,
multi_start: bool | None = None,
p0_starts: Sequence[float] | None = None,
p1_starts: Sequence[float] | None = None,
strategy: Literal["seeded", "multistart"] = "seeded",
order: Literal["auto", 1, 2] | None = None,
) -> Self | tuple[Self, tuple[float, ...]]
Apply automatic phase correction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method
|
Literal['acme', 'peak_minima']
|
Objective used by |
'acme'
|
peak_width
|
int
|
Width of the ROI for the |
100
|
return_phases
|
bool
|
Whether to also return the applied phases: |
False
|
verbose
|
bool
|
Whether to log the optimisation process. |
False
|
multi_start
|
bool | None
|
Try multiple starting points. Accepted by
|
None
|
p0_starts
|
Sequence[float] | None
|
Explicit zero-order starting points in degrees, defaulting to 8
points spanning 0-315 deg. Accepted by |
None
|
p1_starts
|
Sequence[float] | None
|
Explicit first-order starting points in degrees, defaulting to
|
None
|
strategy
|
Literal['seeded', 'multistart']
|
Which algorithm to use.
|
'seeded'
|
order
|
Literal['auto', 1, 2] | None
|
Model order for the seeded strategy -- |
None
|
Returns:
| Type | Description |
|---|---|
Self | tuple[Self, tuple[float, ...]]
|
Self if return_phases=False (default), otherwise (Self, phases). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If a multi-start-only argument is supplied to the seeded strategy. |
ProcessingParameterError
|
If the model order is not recognised. |
correct_phase_manual
#
correct_phase_manual(
p0: float,
p1: float = 0.0,
method: Literal["linear", "exponential"] = "linear",
p2: float = 0.0,
) -> Self
Apply manual phase correction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
p0
|
float
|
Zero-order phase correction (degrees) |
required |
p1
|
float
|
First-order phase correction (degrees) |
0.0
|
method
|
Literal['linear', 'exponential']
|
Manual phase correction method |
'linear'
|
p2
|
float
|
Second-order phase correction (degrees). Supported by |
0.0
|
Returns:
| Type | Description |
|---|---|
Self
|
Self |
to_ppm
#
Convert spectrum to PPM scale.
Returns:
| Type | Description |
|---|---|
Self
|
New spectrum in PPM units (or copy if already in PPM) |
Raises:
| Type | Description |
|---|---|
ValueError
|
If reference frequency is not set |
smooth
#
Apply Gaussian smoothing to spectrum.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sigma
|
float
|
Standard deviation for Gaussian kernel |
4.0
|
preserve_integral
|
bool
|
Whether to preserve total integral |
True
|
Returns:
| Type | Description |
|---|---|
Self
|
Self |
trim_frequency_range
#
Trim spectrum to specified frequency range.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f_min
|
float
|
Minimum frequency (in spectrum's current units) |
-inf
|
f_max
|
float
|
Maximum frequency (in spectrum's current units) |
inf
|
Returns:
| Type | Description |
|---|---|
Self
|
A new, trimmed spectrum (the original is left unchanged). |
center_spectrum
#
Center the spectrum by shifting the main peak to 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method
|
str
|
Centering method ("max" or "centroid") |
'max'
|
Returns:
| Type | Description |
|---|---|
Self
|
Self |
convert_frequency_unit
#
convert_frequency_unit(
target_unit: FrequencyUnit,
reference_freq_hz: float | None = None,
) -> Self
Convert spectrum to different frequency unit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_unit
|
FrequencyUnit
|
Target frequency unit. |
required |
reference_freq_hz
|
float | None
|
Reference frequency in Hz, required when converting to or
from PPM. If omitted, the spectrum's own |
None
|
Raises:
| Type | Description |
|---|---|
ProcessingParameterError
|
If a PPM conversion is requested and no reference frequency is available from either source. |
shift
#
Shift the frequency axis by a constant amount.
If shift_unit is PPM, requires reference_frequency_hz.
interpolate_at
#
Interpolate spectrum at given frequencies.
_is_one_sided_spectrum
#
Detect whether the frequency axis covers only non-negative frequencies.
Prefers the fft_method recorded in metadata by Signal1D.to_spectrum;
falls back to inspecting the axis (a two-sided, fftshift-ordered axis always
contains negative frequencies).
normalize
#
Normalize spectrum amplitudes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method
|
Literal['max', 'rms', 'unit']
|
Normalization method: - "max": Divide by maximum absolute value - "rms": Divide by RMS value - "unit": Divide by L2 norm |
'max'
|
Returns:
| Type | Description |
|---|---|
Self
|
Self for method chaining |
frequency_shift
#
Shift the frequency axis (used by center_spectrum).
apply_window_notch
#
Apply a notch filter around center_hz (used by remove_peak).
The centre and the width are both expressed against the carrier, the same relation the PPM axis itself is built on, so a notch lands on the same position whichever unit the axis is stored in.
__getitem__
#
- slice/int -> Spectrum1D view copy using NumPy-first arrays
- array of frequencies -> complex amplitudes via linear interpolation
to_signal
#
to_signal(
time_unit: TimeUnit = MICROSECOND,
carrier_offset_hz: float | None = None,
half: bool = False,
one_sided: bool | None = None,
first_point_scale: bool | None = None,
) -> Signal1D
Convert spectrum back to time-domain signal via inverse FFT.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
time_unit
|
TimeUnit
|
Time unit for the output signal (default: MICROSECOND) |
MICROSECOND
|
carrier_offset_hz
|
float | None
|
Carrier offset in Hz. If provided, this offset is subtracted from frequencies before inverse FFT and stored in the output signal. |
None
|
half
|
bool
|
If True, return only the first half of the signal. Useful when the spectrum produces a mirrored/symmetric signal after IFFT. |
False
|
one_sided
|
bool | None
|
Whether the frequency axis holds only non-negative frequencies
(as produced by |
None
|
first_point_scale
|
bool | None
|
Whether to undo the forward transform's first-point
halving (doubling |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
Signal1D |
Signal1D
|
Time-domain signal |
_require_reference_for_unit
#
The reference frequency this axis' unit needs, named when it is absent.
Only a PPM axis needs one; other units convert by a fixed factor.