The NMRData model
Every spectrum, FID or series in NMRTools is an NMRData: an array of data points, a set of dimensions describing its axes, and a dictionary of metadata. Loading, processing, plotting and peak picking all take and return NMRData.
using NMRTools
spec = exampledata("2D_HN")
size(spec), eltype(spec)((1216, 512), Float64)An array with axes
NMRData is a subtype of AbstractDimArray from DimensionalData.jl. It behaves like an ordinary Julia array: it can be indexed, sliced, broadcast and passed to functions that expect an AbstractArray. The difference is that each axis carries its coordinates, so the array also answers questions about chemical shift, time or gradient strength:
dims(spec)(↓ F1Dim Sampled{Float64} LinRange{Float64}(11.07119, 5.722488424064256, 1216) ReverseOrdered Regular Points,
→ F2Dim Sampled{Float64} LinRange{Float64}(128.9998, 107.04307400088886, 512) ReverseOrdered Regular Points)Indexing by position and indexing by value use the same square brackets. Value-based selectors come from DimensionalData: Near(x) for the nearest point, At(x) for an exact match, and a .. b for a closed interval:
spec[Near(8.5), 120 .. 121]┌ 23-element NMRData{Float64, 1} ┐
├────────────────────────────────┴─────────────────────────────────────── dims ┐
↓ F2Dim Sampled{Float64} LinRange{Float64}(120.96475545629396, 120.01945609821092, 23) ReverseOrdered Regular Points
├──────────────────────────────────────────────────────────────────── metadata ┤
Dict{Symbol, Any} with 20 entries:
:filename => "/home/runner/.julia/artifacts/278430abd2b28a265273e7074…
:channels => Dict{Symbol, Any}(:f1=>Dict{Symbol, Any}(:offsethz=>2819…
:label => "13C,15N ubiquitin"
:ns => 2
:temperature => 276.999
:experimentfolder => "/home/runner/.julia/artifacts/278430abd2b28a265273e7074…
:pulseprogram => "sfhmqcf3gpph.cw"
:ndim => 2
:acqusfilename => "/home/runner/.julia/artifacts/278430abd2b28a265273e7074…
:title => "13C,15N ubiquitin\n500 uM in 10% D2O, 20 mM Pi pH 6.5, …
:acqus => Dict{Symbol, Any}(:fcuchan=>Dict(0=>0, 4=>0, 5=>0, 6=>0,…
:field => 14.0967
:format => :pdata
:noise => 502.842
:solvent => "H2O+D2O"
:nuclei => Set(Nucleus[H1, N15])
:topspin => v"6.0.0"
:acqu2s => Dict{Symbol, Any}(:origin=>nothing, :sw=>21.9971, :sw_h=…
:date => DateTime("2019-11-20T19:41:09")
:rg => 203
└──────────────────────────────────────────────────────────────────────────────┘
⋮ ⋱ The result of slicing is another NMRData, with its axes cut to match. A slice through a 2D spectrum is a 1D spectrum that can be plotted, phased or peak-picked like any other.
data(spec) returns the plain array underneath, and data(spec, dim) the plain vector of axis coordinates.
Operations preserve structure
Arithmetic and broadcasting return NMRData with the same axes and metadata:
spec2 = 2 * spec .+ 1
typeof(spec2) == typeof(spec)trueReductions over a dimension, such as sum(spec; dims=F1Dim), keep the remaining dimensions. To build a new NMRData with different data but the same axes and metadata, use rebuild:
rebuild(spec, newdata)Element types
The element type records what kind of data an NMRData holds:
| Element type | Meaning | Produced by |
|---|---|---|
Float64 | real spectrum | loadnmr (default), autoprocess, real, realest |
Multicomplex{Float64,1,2} | complex in one dimension | loadfid on a 1D or pseudo-2D, loadnmr(...; allcomponents=true) on 1D data |
Multicomplex{Float64,2,4} | complex in two dimensions | loadfid on a 2D |
Multicomplex{Float64,3,8} | complex in three dimensions | loadfid on a 3D |
Processing keeps the element type unchanged from loadfid to the final phase correction, and realest at the end gives a real spectrum. See Multicomplex numbers and quadrature.
Metadata
Metadata are attached at two levels: to the spectrum as a whole (spec[:ns]) and to each dimension (spec[F1Dim, :bf]). See Metadata.
Related pages
- Dimensions: the dimension types and what they mean
- Working with spectra: a tutorial on indexing, axes and metadata
- DimensionalData.jl: selectors,
rebuild,setand other functions re-exported by NMRTools