API: Analysis1D

The 1D analysis framework: the entry points (relaxation1d, diffusion1d, tract, calibration1d, kinetics1d), the data types they build (Trace, Planes, Region, Dataset1D), the experiment types and their interface hooks, and the interactive window. See Creating New 1D Analyses for how these fit together.

NMRAnalysis.Analysis1D — Module
Analysis1D

Unified framework for lightweight 1D NMR analyses (relaxation, TRACT, nutation calibration, kinetics, …). See PLAN.md in this directory for the design.

The analysis core operates on plain Trace/Planes/Dataset1D values and has no GUI or NMRData dependency in its computational path (the agreed "keep the science pure" split). NMRData is touched only by the adapters in nmrdata.jl.

Each analysis lives in a single self-contained expt-<name>.jl holding its entry point, type, interface methods, science and presentation - the layout used by GUI2D and Exchange1D. experiments.jl documents the interface and includes them; see expt-tract.jl for the fullest example.

source
NMRAnalysis.Analysis1D.BLANK_RICHTEXT — Constant
BLANK_RICHTEXT

Placeholder for "nothing to show". An empty RichText renders zero glyphs, and Makie's GlyphCollection cannot build itself from a zero-length glyph vector: it cannot infer rotations as Vector{Quaternionf} from an empty comprehension, and errors rather than rendering blank. A single space has one glyph and is invisible. Without it, resultstext crashes for every region of a NoFitting experiment and any region not yet fitted.

source
NMRAnalysis.Analysis1D.NOISE_LABEL — Constant
NOISE_LABEL

The label of the row in regionlist.csv that records the noise position rather than a signal region. Reserved: a signal region of this name would be read back as the noise marker.

source
NMRAnalysis.Analysis1D.CurveFitModel — Type
CurveFitModel(func, paramnames, estimate; xlabel, ylabel)

A parametric model fitted to (x, y) with func(x, p). estimate(x, y) returns initial parameters. Mirrors the ParametricModel pattern in GUI2D's models.jl.

source
NMRAnalysis.Analysis1D.Dataset1D — Type
Dataset1D(planes, noisecenter, [label, [sources]])

The planes plus the universal noise position (ppm), a label saying where the data came from, and sources, the same per plane. Both are plain Strings, so results files can name what they were computed from without NMRData re-entering the analysis core.

sources is per plane because an experiment may combine files: TRACT loads a TROSY and an anti-TROSY spectrum. It defaults to label repeated. It is not a plane variable, being provenance rather than a coordinate: two files may be replicates with identical coordinates.

Only the noise centre is stored. The noise region takes the width of whichever signal region is being measured, which is what makes its integral a direct estimate of that region's noise (see integrate).

source
NMRAnalysis.Analysis1D.DiffusionExperiment — Type
DiffusionExperiment(dataset; γ, δ, Δ, σ, Gmax, temp=nothing, solvent=nothing, regions=…)

Fit integrated intensity vs relative gradient strength (vars.gradient, 0–1) to the Stejskal–Tanner equation. The fitted D is the diffusion coefficient; postfit! adds the hydrodynamic radius via the Stokes–Einstein relation when the solvent and temperature are known.

source
NMRAnalysis.Analysis1D.Experiment1D — Type
Experiment1D

Abstract supertype for 1D analyses. A concrete experiment is a thin composition supplying a dataset, a list of regions, a series model, and the fit-axis and grouping designation; the generic analyse pipeline does the rest. Only fitaxis is required; every other hook has a default, and the defaults below assume fields named dataset, regions and model.

One file per experiment, expt-<name>.jl, included at the foot of this file. See docs/src/advanced/creating_1d_analyses.md for the file layout and the full list of hooks, and expt-tract.jl for the fullest example.

source
NMRAnalysis.Analysis1D.Integration — Type
Integration(peakppm, noiseppm, ppmwidth)

The integration triple shared with Exchange1D (prob.integration): a peak position, a noise position, and a common width, all in ppm. The noise region always takes the same width as the signal region, so its own uncertainty matches (see integrate). Passing one to an entry point skips the GUI and analyses directly.

source
NMRAnalysis.Analysis1D.KineticsExperiment — Type
KineticsExperiment(dataset; regions=[defaultregion(dataset)], model=NoFitting())

Track integrated intensity of one or more named regions vs time (vars.time), grouped by run (vars.run) when present. regions defaults to a single peak-detected region; use the GUI (press A) to add further named regions of interest interactively rather than specifying them up front. v1 defaults to NoFitting (the deliverable is the intensity-vs-time trace); a kinetic CurveFitModel can be supplied to fit a model. A future iteration will add an NMF reduction over selected ROIs.

source
NMRAnalysis.Analysis1D.NutationExperiment — Type
NutationExperiment(dataset; phase=:sine, regions=…)

Fit integrated intensity vs pulse duration (vars.duration) to a damped sinusoid and derive the 90° pulse length (1/(4ν)) and B₁ inhomogeneity. Where the planes carry more than one power level (vars.power, in dB), each is fitted as its own series and the results combined into a calibration curve. A height (zero-width region at the observed signal) is the natural reduction but a finite region works identically.

source
NMRAnalysis.Analysis1D.Planes — Type
Planes(traces, vars)

Long-format collection of 1D spectra: one Trace per row, with vars[i] a NamedTuple giving the values of the arrayed acquisition variables for that spectrum (e.g. (; time = 0.1, which = :trosy)). All rows must share the same set of variable names.

source
NMRAnalysis.Analysis1D.Region — Type
Region(label, lo, hi)
Region(label, δ)

A named chemical-shift interval (ppm) used for integration. lo/hi are stored sorted, so the order in which the bounds are supplied does not matter. A zero-width region (lo == hi, or the single-shift constructor) selects the nearest point — i.e. a peak height.

source
NMRAnalysis.Analysis1D.RegionResult — Type
RegionResult

Everything an analysis reports for one region: its series, one SeriesResult per grouping key, and one flat set of parameters. The 1D analogue of GUI2D's Peak.

A series' fitted parameters are named apart by seriesname (:R_trosy, :R_anti) and sit alongside whatever postfit! derives from them (:tauc), so one region is one row of results. Values are untyped: a viscosity looked up from temperature is a plain number where a fitted rate is a Measurement.

Parameters are stored in the unit paramunit names for them (a 90° pulse in µs, τc in ns), not in SI, so one stored number serves both the summary and any tabular export.

source
NMRAnalysis.Analysis1D.RelaxationExperiment — Type
RelaxationExperiment(dataset; model=:exponential, regions=…)

Fit integrated intensity vs relaxation delay (vars.time) to a single exponential (model = :exponential) or to a recovery curve (model = :recovery); any SeriesModel may also be passed directly. A single integration region (override via regions).

source
NMRAnalysis.Analysis1D.ResultSeries — Type
ResultSeries

One coloured curve in the result panel: observed points (Vector{Point2f}), errors (Vector{NTuple{3,Float64}} of (x, y, σ)), a fitline (Vector{Point2f}, empty if unfitted), and a label (e.g. the TRACT which, or kinetics' run; empty for an ungrouped single series).

source
NMRAnalysis.Analysis1D.ResultVisualisation — Type
ResultVisualisation

How an experiment's results are drawn in the fit panel. A hierarchy orthogonal to Experiment1D, joined by visualisationtype, as GUI2D's VisualisationStrategy is to its Experiment, so a presentation can be shared or swapped without touching the science.

A strategy implements three methods:

  • completeresultstate!(state, expt, ::V) — build the Observables the panel reads
  • resultpanel!(gui, state, expt, ::V) — the live GUI panel
  • plotresult!(ax, expt, result, label, i0, ::V) — the static CairoMakie export

The live and export paths share one data getter (here resultplotdata) so that what is saved is what was on screen.

SeriesVisualisation covers every curve-fit experiment and is the default.

source
NMRAnalysis.Analysis1D.SeriesModel — Type
SeriesModel

Abstract supertype for the rule mapping a quantity series to derived parameters.

  • CurveFitModel: a continuous fit-axis, fitted by nonlinear least squares.
  • NoFitting: carry the reduced quantities through unfitted, for an experiment whose deliverable is the series itself (kinetics), or one that needs to transform the series before fitting it in postfit! rather than fitting the measured quantities directly.
source
NMRAnalysis.Analysis1D.SeriesResult — Type
SeriesResult

One measured series of a region: the planes sharing a grouping key, the quantity measured in each, and the curve fitted through them.

x is the sorted evolution parameter, y the measured quantities, planes the dataset plane each point came from (so the series file can name its source spectrum), and coefficients the model's fitted coefficients in paramnames order, named onto the region by liftparameters!.

source
NMRAnalysis.Analysis1D.Trace — Type
Trace(δ, y)

A single 1D spectrum: a chemical-shift axis δ (ppm) and intensities y.

Plain vectors, with no dependency on NMRData, Makie or GUI state: the analysis layer operates on Traces, and the adapters in nmrdata.jl convert NMRData into them.

source
NMRAnalysis.Analysis1D.TractExperiment — Type
TractExperiment(dataset; ωN, f, regions=…)

Fit TROSY and anti-TROSY decays (grouped by vars.which ∈ {:trosy, :anti}) and derive the rotational correlation time τc from the cross-correlated relaxation-rate difference ΔR = R(anti) − R(trosy). ωN is the ¹⁵N Larmor frequency (rad s⁻¹) and f the dipole/CSA cross-correlation prefactor (see tractf).

source
NMRAnalysis.B1Calibration — Method
B1Calibration(results::AbstractVector{RegionResult}; kwargs...)
B1Calibration(result::RegionResult; kwargs...)
B1Calibration(specs::AbstractVector; kwargs...)
B1Calibration(spec; kwargs...)

The B₁ calibration a nutation analysis measured: the field fitted at each power level, and the smallest of its B₁ inhomogeneity estimates.

Pass the results of calibration1d, having checked the fits in the analysis window, or pass the calibration experiments themselves to have them fitted without a window opening (which is what exchange1d(…; calibration=["cal/1", …]) does; keywords are forwarded to calibration1d). To keep the analysis behind it as well as the calibration itself, use calibrationanalysis, which hands back both. Where several regions were integrated, the first is the calibration; the others are presumably there for comparison.

Every power level has to be known, since a calibration is a map from power to field: give them with power=, or annotate the sequence with calibration.power.

Example

cal = B1Calibration(calibration1d(["cal/1", "cal/2"]))
hz(Power(12.0, :dB), cal)     # field at a power the calibration did not measure
source
Base.show — Method
show(io, result::RegionResult)

One line per region: its label followed by every parameter reported for it, so that closing an analysis window prints a short table rather than pages of measured points.

Units are absent, being the one thing a RegionResult cannot know: paramunit is dispatched on the experiment. The results panel, summary.txt and the CSVs carry them.

source
NMRAnalysis.Analysis1D.DampedSinusoidModel — Method
DampedSinusoidModel(; phase = :sine)

Nutation of an inhomogeneous B₁ field: A·sin(2π·ν·t)·exp(−½(2π·σ·ν·t)²) (or cos when phase = :cosine), parameters [A, ν, σ].

ν is the mean nutation frequency (Hz), from which the 90° pulse length follows as 1/(4ν), and σ is the width of the B₁ distribution as a percentage of ν, which is what damps the nutation: averaging sin(2πνt) over a Gaussian distribution of ν with mean ν̄ and standard deviation σν̄ gives sin(2πν̄t)·exp(−½(2πσν̄t)²), a Gaussian decay rather than an exponential one. Fitting the envelope this way makes σ the same quantity B1Distribution later samples, instead of an exponential rate needing conversion.

σ is fitted in percent rather than as a fraction so that every inhomogeneity this analysis reports is in the unit it is quoted in, and incidentally so that the three parameters are of comparable magnitude, which is what a Levenberg-Marquardt step prefers.

Relaxation during the pulse damps the nutation too, and is not separated here: σ is therefore an upper bound, worst at the lowest power where the pulses are longest, which is why a multi-power calibration reports the smallest of its estimates.

Only σ² enters, so the fitted sign is arbitrary and postfit! reports |σ|.

source
NMRAnalysis.Analysis1D.RecoveryModel — Method
RecoveryModel()

Inversion/saturation recovery A·(1 − C·exp(−R·t)), parameters [A, C, R]. Used only here: TRACT always fits a plain exponential (ExponentialModel, shared in seriesmodels.jl since both experiments use it), never a recovery curve.

source
NMRAnalysis.Analysis1D.StejskalTannerModel — Method
StejskalTannerModel(; γ, δ, Δ, σ, Gmax)

Stejskal–Tanner diffusion decay A·exp(−(γ·δ·σ·g·Gmax)²·(Δ−δ/3)·D), fitted against the relative gradient strength g (0–1). Parameters are [A, D] with D in units of 10⁻¹⁰ m² s⁻¹ (as in the legacy routine), so the physical coefficient is D · 1e-10.

source
NMRAnalysis.Analysis1D.__init__ — Method

Register the interactive 1D analyses with the analysis-dispatch registry, so analyse routes annotated experiments here. These replace the registrations previously made by the readline-based routines.

Only the analyses that can run from a filename alone are registered: TRACT needs a TROSY/anti-TROSY pair, diffusion needs the gradient list, and kinetics needs named regions, so those are invoked directly rather than dispatched.

source
NMRAnalysis.Analysis1D.addregion! — Method
addregion!(state, lo, hi)

Add a new region spanning lo..hi (order-independent) and select it. Callers that want the user to immediately name it (as the GUI's 'A' shortcut does) follow up by entering rename mode themselves.

source
NMRAnalysis.Analysis1D.analyse — Method
analyse(e, [dataset, regions]; isfitting=true) -> Vector{RegionResult}

Run the full analysis: measure, fit, then post-fit. The return type does not depend on the experiment or on whether anything was fitted, which is what lets the GUI's state[:result] Observable keep a stable element type while it is still empty.

source
NMRAnalysis.Analysis1D.analyse1d — Method
analyse1d(experiment) -> Vector{RegionResult}

Run a 1D analysis. Equivalent to analyse on an Experiment1D; provided under a distinct name so it can be re-exported without colliding with the registry-based analyse dispatcher in the parent module.

source
NMRAnalysis.Analysis1D.askpowers — Method

Power levels, asked for in the dB attenuation the spectrometer sets them as. Returns nothing without prompting, an unknown power costing only the calibration curve.

source
NMRAnalysis.Analysis1D.baseparam — Method
baseparam(name) -> Symbol

The quantity a parameter name refers to, with any series suffix removed: :R_trosy → :R. Labels and units are looked up under this name.

source
NMRAnalysis.Analysis1D.beginrename! — Method
beginrename!(state; initiator=:mouse)

Begin renaming the active region (shared by the button and the 'R' key). When triggered :keyboard, the same keypress that opened rename mode also emits a unicode-input event for its own character (e.g. 'r') a moment later — enter the intermediate :renamingstart mode so setupkeyboard!'s unicode handler can swallow that spillover character rather than prepending it to the new name (mirrors the 2D fitting GUI's rename handshake).

source
NMRAnalysis.Analysis1D.calibration1d — Method
calibration1d(spec; durations=nothing, phase=nothing, power=nothing, regions=nothing,
              integration=nothing, window=true, prompt=isinteractive())
calibration1d(specs::AbstractVector; ...)

Analyse a 1D nutation calibration, reporting the nutation frequency, 90° pulse length and B₁ inhomogeneity, then open the analysis window.

Given several spectra recorded at different power levels, each is fitted separately and the results combined into a calibration curve: the field at a reference power and the linearity of the amplifier's response, 1 being the ideal ν₁ ∝ √W. A single spectrum still calibrates, with the linearity assumed ideal. Either way B1Calibration(results) turns the analysis into the calibration that exchange1d takes, so CEST and R₁ρ are simulated with measured field strengths and a measured B₁ inhomogeneity rather than nominal ones.

Pulse durations are taken from durations if given, else from the calibration.duration annotation, and otherwise you are asked for them; the modulation likewise from phase, else the calibration.model annotation, else a question; the power level from power, else the calibration.power annotation, else a question. None of the annotations is required, and an unknown power costs only the calibration curve, not the analysis.

Arguments

  • durations: pulse durations, in seconds, one per spectrum of the series. Applies to every spectrum given; where they differ, each spectrum's own annotation is what to rely on.
  • phase: :sine (starting from equilibrium) or :cosine (from transverse magnetisation).
  • power: the power each spectrum was recorded at, as Powers or as numbers in dB, one per spectrum.
  • regions: integration regions to start from, instead of one on the tallest peak.
  • integration: a (; peakppm, noiseppm, ppmwidth) triple, which skips the window and analyses that region directly.
  • window: whether to open the analysis window at all. false analyses the default region (the tallest peak) without one, which is how calibrationanalysis fits a calibration without interrupting the analysis that asked for it.
  • prompt: whether to ask for anything that could not be determined. Defaults to false outside an interactive session, where a missing value raises an error instead.

Example

results = calibration1d(["cal/1", "cal/2", "cal/3"])
cal = B1Calibration(results)      # ready for exchange1d(...; calibration=cal)
source
NMRAnalysis.Analysis1D.calibrationanalysis — Method
calibrationanalysis(specs; kwargs...) -> (calibration, save)

Fit nutation calibration experiments without a window, returning the B1Calibration they measure and a function that writes the analysis into a folder, given one.

Whether and where those results are kept is for the analysis that asked for the calibration to decide: a calibration fitted on the way to an exchange fit belongs inside that fit's output folder, written when it is written, and not written at all if the fit is abandoned. Keywords are calibration1d's.

Example

cal, save = calibrationanalysis(["cal/1", "cal/2"])
save(joinpath("out", "calibration"))     # fit.pdf, calibration.pdf, summary.txt, …
source
NMRAnalysis.Analysis1D.calibrationplot — Method
calibrationplot(cal) -> Figure

The calibration curve: the field measured at each power level, the fitted power law through them, and the residuals from it.

ν₁ is drawn on a log axis against power in dB, the coordinates in which the ideal law is a straight line, so amplifier compression shows as curvature. The deviations are a percent or two and invisible against a decade of field strength, hence the residual panel underneath, in percent rather than in σ: what matters here is how far the amplifier departs from the law, not how that compares with the fitting uncertainty.

source
NMRAnalysis.Analysis1D.centre — Method
centre(region) -> Float64

Midpoint of a region (ppm). Regions are stored by their bounds, but centre-and-width is the natural handle for interaction, so both views are available.

source
NMRAnalysis.Analysis1D.commitondefocus! — Method
commitondefocus!(tb::Textbox)

Commit tb's displayed text to stored_string when it loses focus. Makie's Textbox only commits on Enter; clicking away otherwise leaves the typed text on screen without ever applying it to stored_string (and hence to whatever listens on it).

source
NMRAnalysis.Analysis1D.completeresultstate! — Method
completeresultstate!(state, expt, ::SeriesVisualisation)

Per-series plot data for the active region (one entry per group, e.g. TRACT's TROSY/anti-TROSY), flattened into the contiguous, coloured arrays Makie plot objects want - one scatter!/lines! per panel rather than a variable number of separate plot calls.

source
NMRAnalysis.Analysis1D.coordinateunit — Method
coordinateunit(expt, name) -> String

ASCII unit for a coordinate, the fit axis or a grouping variable, as it appears in a column header. Kept apart from paramunit because the two name spaces are independent: nothing stops an experiment arraying a variable named like a fitted parameter. Categorical coordinates (:which, :run) and relative ones (:gradient) have no unit.

source
NMRAnalysis.Analysis1D.datasetfromspec — Method
datasetfromspec(spec, vars; noisecenter=defaultnoisecentre(spec)) -> Dataset1D

Build a Dataset1D from a pseudo-2D spec and a vector of per-plane variable NamedTuples (length(vars) == number of planes).

source
NMRAnalysis.Analysis1D.defaultamideregion — Method
defaultamideregion(; label="amide") -> Region

TRACT integrates the bulk backbone amide envelope rather than a single resolved peak, so its default region is the conventional 7.5-9.5 ppm amide window - unlike every other experiment's defaultregion, which centres a narrow window on the tallest peak.

source
NMRAnalysis.Analysis1D.defaultregion — Method
defaultregion(dataset; label="signal", width=defaultregionwidth(...)) -> Region

A sensible default single integration region: width ppm wide (2% of the spectral width by default) centred on the tallest peak (by absolute intensity) of the strongest plane. Used as the default regions for every experiment with a single signal; the GUI lets the user reposition and resize it, or add further regions.

The strongest plane rather than the first, because the first plane of a nutation calibration is recorded at the shortest pulse length and holds no signal, so its tallest point is noise. For a decay or a gradient ramp the first plane is the strongest, and the region is the same either way.

source
NMRAnalysis.Analysis1D.diffusion1d — Function
diffusion1d()
diffusion1d(spec, gradients=nothing; coherence=SQ(H1), δ=nothing, Δ=nothing,
            σ=nothing, Gmax=nothing, regions=nothing, integration=nothing,
            prompt=isinteractive())

Analyse a diffusion experiment, fitting the Stejskal-Tanner equation to extract the diffusion coefficient (and the hydrodynamic radius where the solvent and temperature are known), then open the analysis window.

Called interactively, the acquisition parameters are read from the experiment and offered for confirmation before the window opens, exactly as they must be: Bruker records the gradient pulse length δ (2·p30), the diffusion delay Δ (d20) and the gradient shape (gpnam6), but not the gradient ramp itself, so the initial and final gradient strengths have to be supplied. Anything passed as an argument is taken as given and not asked about.

Arguments

  • gradients: relative gradient strengths (0 to 1), one per spectrum. Supply these for any ramp other than a linear one, which is what the prompt constructs.
  • coherence: the coherence whose gyromagnetic ratio applies (default SQ(H1)).
  • δ: gradient pulse length, in seconds.
  • Δ: diffusion delay, in seconds.
  • σ: gradient shape factor (0.9 for the smoothed-square SMSQ shapes, 0.6366 for SINE).
  • Gmax: maximum gradient strength, in T m⁻¹ (0.55 on a typical Bruker system).
  • regions: integration regions to start from, instead of one on the tallest peak.
  • integration: a (; peakppm, noiseppm, ppmwidth) triple, which skips the window and analyses that region directly.
  • prompt: whether to ask for anything that could not be determined. Defaults to false outside an interactive session, where a missing value raises an error instead.

Examples

diffusion1d("106")                                    # asks for the gradient ramp
diffusion1d("106", 0.05:0.05:0.95)                    # ramp given explicitly
diffusion1d("106", g; δ=4e-3, Δ=0.1, σ=0.9, Gmax=0.55)  # nothing left to ask
source
NMRAnalysis.Analysis1D.displaylabel — Method
displaylabel(expt, name) -> String

paramlabel for a parameter as stored on a region, which for a fitted one carries the series it came from: :R_trosy shows as "Relaxation rate (trosy)". The quantity comes from baseparam, so an experiment's label table needs only bare names.

source
NMRAnalysis.Analysis1D.estimatefrequency — Method
estimatefrequency(x, y, trig) -> Float64

Initial estimate of the nutation frequency: the frequency whose modulation correlates best with the data, scanned over the frequencies the sampling can resolve.

How much of a period a calibration covers is not something the data say - the annotated sequence runs to a nominal 720°, and the B₁ inhomogeneity is only measurable over several periods - so assuming half a period, as this did before, starts the fit a factor of four out on a real experiment. A coarse matched filter costs nothing next to the fit it seeds, and the scan runs from half a period across the sampled range up to the Nyquist frequency of the pulse-duration increment.

source
NMRAnalysis.Analysis1D.experimentinfo — Function
experimentinfo(expt, [dataset]) -> String

Multi-line description of the experiment, written as the comment header of every CSV. Generic across every experiment - the analysis name, where the data came from, how many spectra and which variables are arrayed are all already known to the framework - so experiments need not override it (GUI2D's equivalent is written out per experiment).

The dataset is passed explicitly because the one the experiment was constructed with still carries the noise position it started at, where the GUI's live dataset carries wherever the user dragged the marker to. Provenance has to describe the data as analysed.

source
NMRAnalysis.Analysis1D.fitaxis — Function
fitaxis(expt) -> Symbol

The arrayed variable forming the x-axis of every series: a relaxation delay, a gradient strength, a pulse duration. Required of every experiment, there being no sensible default.

source
NMRAnalysis.Analysis1D.fitseries — Method
fitseries(model, x, y) -> NamedTuple

Fit model to evolution values x and reduced quantities y (a Vector{Measurement}). Returns (; params, names, model, converged) with params a Vector{Measurement} (value ± standard error). The fit is noise-weighted using the uncertainties carried by y (addressing the "scale fitting by noise" TODO).

source
NMRAnalysis.Analysis1D.fitvalues — Method
fitvalues(series) -> Vector{Float64}

The model evaluated at the measured coordinates, for the I_fit column - not on a fine grid, so that a residual is a subtraction. NaN (written NA) where nothing was fitted.

source
NMRAnalysis.Analysis1D.gradientramp — Method
gradientramp(n; prompt=true) -> Vector{Float64}

Ask for the gradient ramp, which Bruker does not store: the initial and final gradient strengths (%) of a linear ramp over n spectra, matching TopSpin's dosy dialogue. Its quadratic and exponential ramps are not generated here; pass those gradient strengths to diffusion1d directly.

source
NMRAnalysis.Analysis1D.groupname — Method
groupname(expt, group) -> String

Human-readable label for a grouping key: (which = :trosy,) → "trosy", (power = 11.11,) → "11.11 dB".

The unit comes from coordinateunit, the same table that labels the coordinate's column in series.csv, because a curve labelled 11.11 names nothing a reader can act on. A categorical coordinate has no unit and is shown as it stands.

source
NMRAnalysis.Analysis1D.groupseries — Method
groupseries(planes, cols) -> Vector{Pair{NamedTuple,Vector{Int}}}

Group plane indices by the values of the variables named in cols, preserving order of first appearance. With cols = () every plane falls in one group keyed by the empty NamedTuple. A series is the set of planes sharing all grouping variables, differing only in the fit axis.

source
NMRAnalysis.Analysis1D.gui! — Method
gui!(expt::Experiment1D; call=nothing)

Launch the interactive analysis window for expt. call is the AnalysisCall the entry point recorded, which summary.txt prints as a line repeating the analysis; it is nothing when gui! is driven directly rather than through an entry point. The left column overlays all spectral planes with draggable integration region(s) and a noise marker; the result panel below shows the live fit for the active region. The active region is whichever the mouse is over (or was last clicked), named in the right-hand column. Returns the GUI state when the window closes.

Keyboard shortcuts (mirroring the 2D fitting GUI)

  • A: add a region. A quick tap adds a default-width region under the cursor; press, drag, and release to choose the width.
  • R: rename the active region.
  • D: delete the active region.
  • Left/Right arrows: step through spectra.
  • Up/Down arrows: scale the spectrum's y-axis (×2 / ÷2).
  • Shift+scroll: resize the active region, about its own centre.
  • Q: close the window.
source
NMRAnalysis.Analysis1D.integrate — Function
integrate(region, expt[, dataset]) -> Vector{Measurement{Float64}}

Stage 1: reduce region to one measured quantity per plane. The default integrates; an experiment that measures its regions some other way overrides this method.

dataset is separate from the experiment's own so the GUI can measure against interactively-positioned regions and noise.

source
NMRAnalysis.Analysis1D.integrate — Method
integrate(region, dataset) -> Vector{Measurement{Float64}}

Integrate region over every plane of dataset, with an uncertainty attached to each.

The uncertainty is measured rather than taken from spec[:noise]: the noise on an integrated region depends on its width and on the noise where it actually sits, not on the whole-spectrum RMS level. So a noise region of the same width, centred at dataset.noisecenter, is integrated over every plane and the standard deviation of those integrals taken. With uniform noise this approaches sqrt(n points), the trace intensities already being noise-normalised, but it tracks a locally noisier baseline.

source
NMRAnalysis.Analysis1D.integrate — Method
integrate(region, trace) -> Float64

Summed intensity of region in one plane (a height when the region has zero width — the nearest point is taken). The summed intensity is the convention used by the legacy 1D routines and by GUI2D's intensity analysis.

source
NMRAnalysis.Analysis1D.kinetics1d — Method
kinetics1d(spec, times; run=nothing, regions=nothing, model=NoFitting(), integration=nothing)

Track integrated intensity of one or more named regions against times, optionally tagged by run for several time series.

regions defaults to a single peak-detected region; add further named regions of interest interactively in the GUI (press A) rather than specifying them up front.

source
NMRAnalysis.Analysis1D.nextlabel — Method

Number the default label uniquely against the current region list. "peak" rather than "region", so the heading built from it ("Region: peak2") doesn't repeat "region" - and to match the vocabulary GUI2D uses for the same idea.

source
NMRAnalysis.Analysis1D.nutationexperiment — Method
nutationexperiment(specs; durations, phase, power, regions, prompt)
    -> (expt, dataset, regions, call)

Everything calibration1d resolves before it fits: the spectra loaded, their pulse durations and power levels found, the experiment built from them, and the call that would repeat the analysis.

Separate from the entry point so that a calibration fitted on behalf of another analysis can be saved afterwards from the same pieces the entry point would have saved - see calibrationanalysis.

source
NMRAnalysis.Analysis1D.nutationphase — Method
nutationphase(annotation) -> Symbol or nothing

The modulation named by a calibration.model annotation, or nothing where there is no annotation to read - so the entry point can fall through to asking.

source
NMRAnalysis.Analysis1D.panelwidth — Method
panelwidth(expt, result, activelabel) -> Int

The label-column width for the results panel: the longest display label among the parameters shown for activelabel, plus a gap, or nothing when there is nothing to show yet. Computed across the whole panel so "Amplitude (trosy)" and "Correlation time (τc)" share one column.

source
NMRAnalysis.Analysis1D.paramblock — Function
paramblock(io, expt, params, width=nothing)

Write every entry of a parameter dictionary as name value unit, in insertion order, the names padded to width (computed from params alone when omitted) so the values line up. The GUI panel passes a width computed across every region (panelwidth) so the column does not jump as regions are selected; summary.txt leaves it to align to its own block.

source
NMRAnalysis.Analysis1D.parameternames — Method
parameternames(results) -> Vector{Symbol}

Every parameter name present across results, in order of first appearance. The union, so the table stays rectangular when one region derived something another did not.

source
NMRAnalysis.Analysis1D.paramgroups — Method
paramgroups(result) -> Vector{Pair{NamedTuple,OrderedDict{Symbol,Any}}}

A region's parameters split into one block per series, each keyed by that series' grouping key and holding its parameters under their bare names, followed by a block keyed by the empty NamedTuple for whatever belongs to the region rather than to any one series - the quantities postfit! derived from all of them.

This is what turns a flat dump of nu_11.11, nu_31.11, pulse90_11.11 … into something a reader can take in: each condition's results together, under a heading naming it. A region with a single series has one block with an empty key, so nothing is grouped and nothing is indented that was not before.

source
NMRAnalysis.Analysis1D.paramlabel — Method
paramlabel(expt, name) -> String

Display name for parameter name (fitted or derived). Experiment-dispatched: the default falls back to the small shared table above, then to the bare symbol. An experiment that introduces its own parameters overrides this with its own local table - see e.g. NUTATION_PARAM_LABELS in expt-nutation.jl.

source
NMRAnalysis.Analysis1D.paramtext — Function
paramtext(expt, params, width=nothing) -> String

paramblock, returned as a string rather than written to an IO - the form the GUI panel wants, built from the same alignment logic summarytext uses for summary.txt so the two never drift apart. Empty (not a blank line) when params is empty, so a caller can skip a block that has nothing to show.

source
NMRAnalysis.Analysis1D.paramunit — Method
paramunit(expt, name) -> String

Unit for parameter name, dispatched and overridden as paramlabel is.

Units are held in ASCII ("s-1", "us", "1e-10 m2/s"), because that is the form the CSV column headers carry and a file header must survive being opened on any machine - see docs/src/advanced/conventions.md. prettyunit turns one into the typeset form for the GUI panel and summary.txt, so there is one table rather than two that can drift.

source
NMRAnalysis.Analysis1D.paramwidth — Method
paramwidth(expt, groups) -> Int

Width of the label column across every block of paramgroups, indentation included, so the values line up down the whole region and not just within a block. Zero where there is nothing to show.

source
NMRAnalysis.Analysis1D.pickregion — Method
pickregion(traces; peakppm=nothing, noiseppm=nothing, ppmwidth=defaultregionwidth(...)) -> (; peakppm, noiseppm, ppmwidth)
pickregion(specs; kwargs...)

Interactively choose a single integration region and a noise position, returning the integration triple. All traces are overlaid, so a region can be chosen that suits every spectrum at once - which is what is wanted when one region must serve a whole set of experiments (e.g. Exchange1D's integrate!, which applies one triple to every experiment in the problem). Drag the peak region or noise marker to move it, its edges to resize it, type an exact ppm value into the text boxes, or Shift+scroll to resize - matching gui!'s main GUI.

This is the region-selection front-end on its own, without any fitting: use it where the heavy fitting lives elsewhere.

source
NMRAnalysis.Analysis1D.plaintext — Method
plaintext(text) -> RichText

Wrap text in an explicit font=:regular span. A RichText font is not scoped to each sibling: a plain String child inherits whatever font the previous sibling left active, so without this a parameter block following a bold heading renders bold too.

source
NMRAnalysis.Analysis1D.planevars — Method

Per-plane variables for one spectrum of a calibration: the pulse duration always, and the power level where it is known. Powers are rounded to the 0.01 dB they are set to on the spectrometer, so that the series they name carries a legible column header.

source
NMRAnalysis.Analysis1D.plotresult! — Method
plotresult!(ax, expt, result, label, i0, ::SeriesVisualisation) -> Int

Draw region label into a static axis, starting colour indices at i0 + 1; returns the number of series drawn, so callers can decide whether a legend is worthwhile. Shares resultplotdata with the live panel, so an exported plot matches what was on screen.

source
NMRAnalysis.Analysis1D.plotseries! — Method
plotseries!(ax, series, colour; label=nothing)

Draw one measured series and its fit into an axis: error bars, points, and the fitted curve where there is one. The one place a series becomes marks on a plot, so an experiment laying its series out differently (resultfigure) draws them the same way.

source
NMRAnalysis.Analysis1D.postfit! — Method
postfit!(result, expt)

Stage 2: derive the quantities reported for one region from its fitted series, recording them with setpost! - nutation's 90° pulse from ν, diffusion's rH from D, TRACT's τc from both rates. result holds every series of the region, so anything combining conditions belongs here rather than in postfitglobal!. The default derives nothing.

source
NMRAnalysis.Analysis1D.postfitglobal! — Method
postfitglobal!(results, expt)

Stage 3: fit or derive quantities spanning every region of the analysis, and record them on the relevant results. Runs after every postfit!. Mirrors GUI2D's postfitglobal!(expt).

source
NMRAnalysis.Analysis1D.powerdb — Method
powerdb(power) -> Vector{Float64} or nothing

Power levels as dB attenuation: Powers converted, bare numbers taken to be dB already, and nothing where any of them is missing - a calibration curve needs every power or none.

source
NMRAnalysis.Analysis1D.ppmbox! — Method
ppmbox!(fig, parent, row, col, obs; digits=3, boxwidth=90)

A chemical-shift text box two-way bound to obs: typing a number sets it, and dragging the corresponding marker on the plot rewrites the displayed text.

source
NMRAnalysis.Analysis1D.preparestate — Method
preparestate(expt) -> Dict{Symbol,Any}

Build the Observable graph for expt: regions (position/width/label), the noise marker position, current spectrum, GUI interaction mode, and the live analysis result with its derived plot data.

source
NMRAnalysis.Analysis1D.prettyunit — Method
prettyunit(unit) -> String

The typeset form of an ASCII unit, for display only: "s-1" → " s⁻¹", "us" → " µs". Includes the leading space so it appends to a formatted value, and returns "" for a dimensionless quantity. Anything not in the table is shown as written ("Hz", "ns").

source
NMRAnalysis.Analysis1D.primaryparam — Method
primaryparam(expt) -> Symbol

The experiment's headline quantity: the parameter a reader wants first, listed first among the derived columns of any tabular export. Defaults to the amplitude A that every CurveFitModel here fits. Mirrors GUI2D's primaryparam(expt).

source
NMRAnalysis.Analysis1D.quit! — Method

Close the GUI window, deferred so the click/keypress event finishes first (matches GUI2D's quit!) - calling GLMakie.closeall() synchronously from inside the renderloop's own event callback tears down the GL context while it is still being polled.

source
NMRAnalysis.Analysis1D.readregions! — Method
readregions!(state, filepath) -> Int

Restore a saved region list, replacing whatever is currently set, and return the number of signal regions read. The row labelled noise sets the noise position from its centre; every other row is a region.

Written for regionlist.csv but deliberately tolerant, so that a hand-made list works and so does a results.csv from before the region bounds moved out of it: any file with a label column and lo/hi columns is read, and a # Noise position / ppm: comment is honoured where there is no noise row.

source
NMRAnalysis.Analysis1D.rebuildregionspans! — Method

(Re)create one vspan! per region, coloured to highlight the active one. Called once at startup and again whenever the number of regions changes (add/delete); simple position/width/active-state changes are handled by the spans' own Observables and don't need a rebuild.

Each span's position/colour Observables are plain Observables kept in sync by an explicit on listener (rather than lifting straight off state[:regions]/ state[:active], index i baked in) so the listener can be off'd here before the next rebuild. Without that, an old listener for index i stays registered on state[:regions] after its span is deleted, and fires (indexing out of bounds) the next time a region is removed and the list is shorter than i.

source
NMRAnalysis.Analysis1D.regionlisttable — Method
regionlisttable(regions, noisecentre, defaultwidth) -> (header, rows)

Column names and rows for regionlist.csv: what the user picked, as opposed to what the fit produced. One row per region, plus one for the noise position.

The noise marker has a position but no width of its own - the width used to estimate a region's uncertainty always matches that region's own (see integrate) - so it is written as a region defaultwidth wide, or as wide as the widest signal region where that is wider. Reading its centre back is what matters; the width is there so the row means something on its own and so the file needs no separate convention for it.

source
NMRAnalysis.Analysis1D.relaxation1d — Method
relaxation1d(spec; tau=nothing, model=nothing, regions=nothing, integration=nothing,
             prompt=isinteractive())

Analyse a 1D relaxation experiment (T1/T2, or inversion recovery) from a pseudo-2D spec (a path or an NMRData), then open the analysis window.

Relaxation delays are taken from tau if given, else from the relaxation.duration annotation, else from the vdlist; if none of those is available you are asked for them. The model is taken from model if given, else from the relaxation.model annotation, and otherwise you are asked to choose one. Neither annotation is required.

Arguments

  • tau: relaxation delays, in seconds, one per spectrum.
  • model: :exponential for a decay A exp(-Rt), :recovery for an inversion/saturation recovery A [1 - C exp(-Rt)], or any SeriesModel.
  • regions: integration regions to start from, instead of one on the tallest peak.
  • integration: a (; peakppm, noiseppm, ppmwidth) triple, which skips the window and analyses that region directly.
  • prompt: whether to ask for anything that could not be determined. Defaults to false outside an interactive session, where a missing value raises an error instead.

Examples

relaxation1d("11")                                   # annotations or vdlist, or asks
relaxation1d("11"; tau=[0.01, 0.05, 0.1, 0.5])       # delays given explicitly
relaxation1d("11"; model=:recovery)                  # inversion recovery
source
NMRAnalysis.Analysis1D.relaxationmodel — Method
relaxationmodel(annotation) -> Symbol or nothing

The model named by a relaxation.model annotation, or nothing where there is no annotation to read - so the entry point can fall through to asking.

source
NMRAnalysis.Analysis1D.relaxationseriesmodel — Method
relaxationseriesmodel(model) -> SeriesModel

The curve fitted for a named relaxation model. A SeriesModel passes straight through, so an unusual decay can be supplied directly without a name having to be invented for it.

source
NMRAnalysis.Analysis1D.resultfigure — Method
resultfigure(expt, result, labels) -> Figure

The figure an analysis saves for the regions named in labels: every series of every region on one axis, with a legend where there is more than one.

An experiment whose series do not share an x-range overrides this. A nutation calibration is the case in point: the 90° pulse at the lowest power can be ten times the longest duration sampled at the highest, so one axis shows one series and a spike at the origin.

source
NMRAnalysis.Analysis1D.resultfigure — Method
resultfigure(expt::NutationExperiment, result, labels) -> Figure

One panel per power level rather than one axis for all of them.

The whole point of calibrating at several powers is that they nutate at different rates, so their pulse durations differ by the same factor: 123 µs against 1220 µs here, which on a shared axis leaves the fast series as a spike against the origin. Each series gets its own axis, autoscaled to its own durations, stacked in the order they were measured and labelled once underneath.

source
NMRAnalysis.Analysis1D.resultkeys — Method
resultkeys(expt) -> Vector{Symbol}

The grouping coordinates that, with the region label, identify a row of results.csv: (:which,) for TRACT, (:run,) for a multi-run kinetics series, none for a single-series experiment.

source
NMRAnalysis.Analysis1D.resultplotdata — Method
resultplotdata(expt, result, activelabel) -> Vector{ResultSeries}

Plot primitives for the active region, one ResultSeries per series, so each is drawn in its own colour.

source
NMRAnalysis.Analysis1D.resultstable — Method
resultstable(expt, results) -> (header, rows)

Column names and rows for results.csv: one row per region, carrying every parameter reported for it, with the experiment's primaryparam first. A region measured under several conditions keeps them all on that row under the names seriesname gave them, so TRACT writes R_trosy and R_anti beside the tauc computed from the two.

The region bounds are not here: they are what the user picked, and live in regionlist.csv (see regionlisttable).

source
NMRAnalysis.Analysis1D.resultstext — Function
resultstext(expt, result, activelabel, width=nothing) -> RichText

Every parameter reported for the active region, as one block - the fitted ones under the names their series gave them, then whatever the experiment derived from them. Doesn't repeat the region name, which is already shown elsewhere in the panel.

width aligns the values to a fixed column - see panelwidth; omitted, the block aligns only to its own labels.

source
NMRAnalysis.Analysis1D.resultxfactor — Method
resultxfactor(expt) -> Float64

Multiplier applied to the result panel's x-values for display, 1.0 except where a time-valued axis reads better in ms or µs (see timescale). Fitting always uses the raw values.

source
NMRAnalysis.Analysis1D.roiindices — Method
roiindices(region, trace) -> Vector{Int}

Indices of trace.δ falling within region. For a zero-width region (or one that contains no grid points) the single nearest point is returned, giving a peak height.

source
NMRAnalysis.Analysis1D.run1d — Method
run1d(expt; integration=nothing, call=nothing) -> Vector{RegionResult}

Launch the GUI for expt and return the results standing when its window is closed, or - when an integration triple is supplied - skip the GUI and return the analysis for that region directly.

call is the AnalysisCall the entry point recorded, carried through to summary.txt; it is unused on the scripted path, which writes no files. Both paths return the same thing. gui! returns the whole GUI state, of which this is one entry.

source
NMRAnalysis.Analysis1D.saveanalysis — Method
saveanalysis(expt, dataset, result, regions, folder; call=nothing) -> String

Write an analysis's output folder, with or without a window having been open: the files saveresults describes, in the folder named. Returns the folder written.

The Save button goes through here, and so does an analysis run without a window - a calibration fitted on behalf of exchange1d, say - so what is saved does not depend on how the analysis was run.

source
NMRAnalysis.Analysis1D.saveextras! — Method
saveextras!(expt, results, folder)

Write any further files an experiment reports, beyond the shared set every analysis saves (summary.txt, results.csv, series.csv, fit.pdf and the per-region plots and data). The default writes nothing; nutation writes its calibration curve. Called by saveresults once the shared files are written. Returns the path written, or nothing where there was nothing to write.

source
NMRAnalysis.Analysis1D.saveextras! — Method
saveextras!(expt::NutationExperiment, results, folder)

Write calibration.pdf, the calibration curve, where several power levels were measured. One power level is a point rather than a curve, and gets no plot. As with B1Calibration, the first region carrying a curve is the calibration; any others are there for comparison.

source
NMRAnalysis.Analysis1D.saveresults — Method

Save the results, covering every region (not just the active one shown live in the GUI panels), to the output folder, in the layout described in docs/src/advanced/conventions.md: summary.txt to read, results.csv and series.csv to compute with (results.csv is also the file a region list is restored from

  • see readregions!), an overlay of every region in fit.pdf, and a regions/ folder

holding each region's own plot and the data behind it under the same basename. An experiment with anything further to report adds it through saveextras!.

source
NMRAnalysis.Analysis1D.scaleyaxis! — Method

Scale the spectrum axis's y-view by factor - factor=2 makes peaks look twice as tall (divides both bounds by 2, i.e. halves the range), factor=0.5 half as tall (doubles the range). Scales ymin/ymax directly rather than re-centring on the current view's midpoint, so it stays anchored to the data's own zero rather than drifting off-centre over repeated presses. The axis's y-interaction is locked (yzoomlock), so this is the controlled replacement for scroll/drag y-zoom - a button/keyboard shortcut rather than the mouse.

source
NMRAnalysis.Analysis1D.seriesname — Method
seriesname(name, group) -> Symbol

The name a series' fitted parameter takes among its region's parameters: bare when the region has one series, suffixed with the grouping values when it has several, so TRACT's two decay rates become :R_trosy and :R_anti. Parameter names carry no underscore of their own, so baseparam can strip the suffix again.

source
NMRAnalysis.Analysis1D.seriesnames — Method
seriesnames(expt) -> Union{Nothing,Vector{String}}

Fixed group names (in seriescolor order) for the result panel's legend, when the experiment's groups are few and consistently named (e.g. TRACT's TROSY/anti-TROSY pair) - axislegend is used instead of labelling each curve directly. nothing (the default) keeps the inline curve labels, which suit experiments whose group count/names vary per dataset (e.g. kinetics' runs, when several are present).

source
NMRAnalysis.Analysis1D.seriesresults — Method
seriesresults(e, [dataset, regions]; isfitting=true) -> Vector{RegionResult}

Measure and fit every region's series, for every grouping key, without the post-fit stage. This is the pipeline shared by every curve-fit experiment.

The dataset/regions arguments default to the experiment's own, but can be supplied explicitly so the GUI can refit live against interactively-positioned regions and noise. isfitting=false (the GUI's Fitting toggle switched off) substitutes NoFitting for the experiment's own model: the measured quantities still come through for the plotted points, but no curve_fit call runs and the region's parameters come back empty.

source
NMRAnalysis.Analysis1D.seriestable — Method
seriestable(expt, dataset, results) -> (header, rows)

Column names and rows for series.csv: the measurements themselves, long, one row per region per plane.

source and plane are always written, even when constant. They are provenance, so whatever physical variable distinguishes several datasets (TRACT's which, a concentration) gets its own coordinate column as well. plane is load-bearing where the planes share one file: every row of a pseudo-2D experiment has the same source.

source
NMRAnalysis.Analysis1D.setregionedge! — Method
setregionedge!(state, i, fixed, moving)

Move one edge of region i to moving, keeping the opposite edge at fixed - so both the centre and width update together. Used for edge-dragging (as opposed to setregioncentre!, which drags the whole region and keeps its width fixed).

source
NMRAnalysis.Analysis1D.setregionwidth! — Method
setregionwidth!(state, i, w)

Resize region i to width w about its current centre (as opposed to setregionedge!, which changes the centre along with the width). Used by shift+scroll resizing.

source
NMRAnalysis.Analysis1D.setupkeyboard! — Method

Wire keyboard shortcuts: A to add a region (tap or drag), R to rename, D to delete, Left/Right to step through spectra, Up/Down to scale the spectrum's y-axis, Q to quit, matching the 2D fitting GUI's key bindings.

source
NMRAnalysis.Analysis1D.shapefactor — Method

Gradient shape factor from the Bruker shape name (as in the legacy routine), falling back to 1.0 where the shape is unrecognised or was not recorded at all.

source
NMRAnalysis.Analysis1D.solventname — Method

The solvent as viscosity names it, or nothing for one it does not know (which leaves the diffusion coefficient reported but not the hydrodynamic radius).

source
NMRAnalysis.Analysis1D.sources — Method
sources(dataset) -> Vector{String}

Where each plane came from, one entry per plane. This is what the source column of series.csv carries.

source
NMRAnalysis.Analysis1D.speclabel — Method

Where a spectrum came from, for results-file provenance: the full path, since a saved file has to say where its data were on the disk. What is shown on screen is shortened instead, by shortpath, which has a panel's width to live within.

source
NMRAnalysis.Analysis1D.spectruminfo — Method
spectruminfo(expt, vars) -> String

One-line description of a single plane, built from its arrayed variables vars (the NamedTuple for that plane, e.g. (; time=0.4, which=:anti)) - shown next to the spectrum slider so the displayed slice is identifiable at a glance (e.g. "0.4 s delay (anti-TROSY)"). The generic fallback lists every variable as key=value; each experiment overrides it with wording natural to its own variables.

source
NMRAnalysis.Analysis1D.stepslice! — Method

Step the spectrum slider by delta planes (clamped to range), moving its visual thumb via set_close_to! (not just .value, which the slider's thumb doesn't track - see setupkeyboard!). Shared by the ←/→ buttons and the Left/Right key shortcuts.

source
NMRAnalysis.Analysis1D.summarytext — Method
summarytext(expt, result, activelabel) -> String

Human-readable summary of the fit for the active region only, shown in the GUI and written to summary.txt (matching the result panel and plot, which are likewise restricted to the active region).

Note

Output-format consistency across the different 1D/2D analyses (units, significant figures, CSV vs text) is an open question — see PLAN.md.

source
NMRAnalysis.Analysis1D.timescale — Method
timescale(times) -> (factor, unit)

Pick a display unit (s / ms / µs) and its multiplying factor for a set of raw times (in s), so values don't show as awkward tiny fractions - e.g. nutation's calibration pulses (tens of µs to ~1 ms) read far more naturally in µs than in s, just as sub-2s relaxation delays read better in ms.

source
NMRAnalysis.Analysis1D.tracesfromspec — Method
tracesfromspec(spec) -> Vector{Trace}

Extract one Trace per plane from an N-dimensional NMRData whose first axis is the chemical shift (F1Dim): a pseudo-2D, or a pseudo-3D such as an off-resonance R1ρ spectrum (shift × spinlock × delay). The non-shift axes are flattened in column-major order into one list of planes.

Intensities are divided by the spectrum's RMS noise level (spec[:noise], computed once by NMRTools on load), so every downstream Trace is in signal-to-noise units. This is distinct from the noise region a user positions, which estimates the uncertainty on an integral (see integrate).

source
NMRAnalysis.Analysis1D.tract — Method
tract()
tract(trosy, antitrosy; tau=nothing, regions=nothing, integration=nothing,
      prompt=isinteractive())

Analyse a TRACT pair, deriving τc from the TROSY / anti-TROSY relaxation-rate difference, then open the analysis window. The two spectra are combined into one dataset tagged by which ∈ {:trosy, :anti}, sharing a single integration region.

Called with no arguments, you are asked for the two experiment folders. Relaxation delays are taken from tau if given, else from each spectrum's own vdlist, and otherwise you are asked for them.

Arguments

  • tau: relaxation delays, in seconds, one per spectrum, used for both experiments.
  • regions: integration regions to start from, instead of the 7.5-9.5 ppm amide window.
  • integration: a (; peakppm, noiseppm, ppmwidth) triple, which skips the window and analyses that region directly.
  • prompt: whether to ask for anything that could not be determined. Defaults to false outside an interactive session, where a missing value raises an error instead.
source
NMRAnalysis.Analysis1D.tractf — Method
tractf(; B0, θ=17π/180) -> Float64

Dipole/CSA cross-correlation prefactor used in the TRACT τc relation, given the static field B0 (T). Constants follow the standard ¹⁵N–¹H amide treatment.

source
NMRAnalysis.Analysis1D.tracttauc — Method
tracttauc(f, ωN, ηxy) -> Float64

Rotational correlation time τc (ns) from the cross-correlated cross-relaxation rate ηxy, by the analytic inversion of

ηxy = f · [4·J(0) + 3·J(ωN)],   J(ω) = (2/5)·τc / (1 + ω²τc²)

i.e. ηxy = f·(8/5·τc + 6/5·τc/(1+(ωN·τc)²)), as in the routine this replaces.

The (2/5) spectral-density convention is the easy thing to lose here: an earlier version of this docstring quoted the relation as 4/5·τc + 3/5·τc/(1+(ωN·τc)²), a factor of two out from what the inversion below actually solves (the code was right, the docstring was not). test/analysis1d_test.jl now round-trips this against the forward relation above, so the two cannot drift apart again silently.

source
NMRAnalysis.Analysis1D.writeresults! — Method
writeresults!(expt, dataset, results, regions, folder) -> String

Write the whole result set into folder: regionlist.csv (what was picked), series.csv, results.csv where anything is reported per region, and one regions/<label>.csv per region holding that region's own rows of series.csv. Returns the path of the series file.

source
NMRAnalysis.Analysis1D.writesummary — Function
writesummary(filepath, expt, dataset, results, regions, call=nothing)

Write summary.txt: the human-readable record of the analysis, and the one output where numbers are rounded for reading rather than written at full precision.

source
NMRAnalysis.callstring — Method
callstring(call, regions, noisecentre) -> String or nothing

The Reproduce: line for summary.txt: the recorded call with the region actually used appended as an integration triple, so pasting it back repeats the analysis without the window opening.

Only a single-region analysis can be repeated in one call, the integration triple carrying one region and one noise position. With several regions the call is still printed, without them, and writesummary adds a line pointing at the Load button, which restores every region and the noise position from results.csv.

source