Metadata

Metadata access

DimensionalData.Dimensions.Lookups.metadata — Function
metadata(nmrdata, key)
metadata(nmrdata, dim, key)
metadata(nmrdimension, key)

Return the metadata for specified key, or nothing if not found. Keys are passed as symbols.

Examples (spectrum metadata)

  • :ns: number of scans
  • :ds: number of dummy scans
  • :rg: receiver gain
  • :ndim: number of dimensions
  • :title: spectrum title (contents of title pdata file)
  • :filename: spectrum filename
  • :pulseprogram: title of pulse program used for acquisition
  • :experimentfolder: path to experiment
  • :noise: RMS noise level

Examples (dimension metadata)

  • :pseudodim: flag indicating non-frequency domain data
  • :npoints: final number of (real) data points in dimension (after extraction)
  • :td: number of complex points acquired
  • :tdzf: number of complex points when FT executed, including LP and ZF
  • :bf: base frequency, in Hz
  • :sf: carrier frequency, in Hz
  • :offsethz: carrier offset from bf, in Hz
  • :offsetppm: carrier offset from bf, in ppm
  • :swhz: spectrum width, in Hz
  • :swppm: spectrum width, in ppm
  • :region: extracted region, expressed as a range in points, otherwise missing
  • :window: WindowFunction indicating applied apodization
  • :referenceoffset: referencing (in ppm) applied to the dimension

See also estimatenoise.

source
DimensionalData.Dimensions.label — Function
label(nmrdata)
label(nmrdata, dim)
label(nmrdimension)

Return a short label associated with an NMRData structure or an NMRDimension. By default, for a spectrum this is obtained from the first line of the title file. For a frequency dimension, this is normally something of the form 1H chemical shift (ppm).

See also label!.

source
NMRTools.NMRBase.label! — Function
label!(nmrdata, labeltext)
label!(nmrdata, dim, labeltext)
label!(nmrdimension, labeltext)

Set the label associated with an NMRData structure or an NMRDimension.

See also label.

source
NMRTools.NMRBase.acqus — Function
acqus(nmrdata)
acqus(nmrdata, key)
acqus(nmrdata, key, index)

Return data from a Bruker acqus file, or nothing if it does not exist. Keys can be passed as symbols or strings. If no key is specified, a dictionary is returned representing the entire acqus file.

If present, the contents of auxilliary files such as vclist and vdlist can be accessed using this function.

Examples

julia> spec = exampledata("2D_HN");

julia> acqus(spec, :pulprog)
"sfhmqcf3gpph.cw"

julia> acqus(spec, "TE")
276.9988

julia> round(acqus(spec, :p, 1) * 1e6; digits=2)    # pulse length p1, in µs
9.2

julia> acqus(spec, "D", 1)
0.1

See also metadata.

source
NMRTools.NMRBase.channels — Function
channels(nmrdata)
channels(nmrdata, label)
channels(nmrdata, nucleus)
channels(nmrdata, string)

Access spectrometer channels. channels returns a dictionary of all channels keyed by label (:f1…:f8), or nothing if no channel information is available. channel returns a single channel dictionary (or nothing if not found).

Each channel dictionary describes a physical RF channel independently of which dimensions were detected, with keys :label, :nucleus, :bf (base frequency, Hz), :sfo (carrier frequency, Hz), :offsethz and :offsetppm (carrier offset from :bf).

A channel can be looked up by label (channels(spec, :f2)), by Nucleus (channels(spec, C13)), or by a string giving either (channels(spec, "f2"), channels(spec, "13C")). When several channels share a nucleus, the lowest-numbered channel is returned and a warning is issued.

This is the recommended way to obtain the frequency of a nucleus that has no detected axis, e.g. the carbon channel in a ¹³C-edited experiment read out on ¹H.

Examples

julia> spec = exampledata("2D_HN");

julia> channels(spec, C13)[:bf]
1.5092041e8

julia> channels(spec, :f1)[:nucleus]
H1::Nucleus = 0

See also acqus, metadata.

source
NMRTools.NMRBase.referencepulse — Function
referencepulse(spec, nucleus) -> (pulse_length, power)

Get the reference pulse calibration for a given nucleus from pulse programme annotations. Returns a tuple of (pulse_length, power) or nothing if not found.

The reference pulse is the calibrated 90° hard pulse used as the basis for all power calculations on that channel.

Arguments

  • spec: NMRData object with annotations
  • nucleus: Nucleus symbol or string (e.g., :19F, "19F", :1H, "1H")

Returns

  • (pulse_length, power): Tuple where pulse_length is in μs and power is a Power object
  • nothing: If no reference pulse found for the specified nucleus

Examples

julia> referencepulse(spec, "19F")
(13.29, Power(-9.03 dB, 8.0 W))

julia> referencepulse(spec, :1H)
(9.2, Power(-3.0 dB, 32.0 W))

See also annotations.

source

Annotations

NMRTools.NMRBase.annotations — Function
annotations(nmrdata)
annotations(nmrdata, key)
annotations(nmrdata, key, index)
annotations(nmrdata, key1, key2)
annotations(nmrdata, keys...)

Return annotation data from pulse programme, or nothing if it does not exist. Keys can be passed as strings or symbols. If no key is specified, the entire annotations dictionary is returned.

Dotted names are automatically split and dereferenced, e.g. annotations(spec, "cest.duration") is equivalent to annotations(spec, "cest", "duration").

This function provides nested access to annotations stored in metadata[:annotations]. Multiple keys can be chained to access nested dictionaries or specific array elements.

Examples

julia> annotations(spec, "title")
"19F CEST"

julia> annotations(spec, "dimensions")
2-element Vector{String}:
 "cest.offset"
 "f1"

julia> annotations(spec, "dimensions", 1)
"cest.offset"

julia> annotations(spec, "cest", "duration")
0.5

julia> annotations(spec, "cest.duration")
0.5

julia> annotations(spec, :reference_pulse)
1-element Vector{Dict{String, Any}}:
 Dict("channel" => "f1", "pulse" => 9.2e-6, "power" => -3.0)

julia> annotations(spec, "calibration.duration.start")
0.001

See also metadata, acqus.

source

Metadata types

NMRTools.NMRBase.Power — Type
Power{T}

A type to represent NMR pulse powers that can be described either in Watts (W) or as dB attenuation (dB). Internally stores the dB value as type T.

Constructors

  • Power(value, :dB) - Create from dB attenuation value
  • Power(value, :W) - Create from Watts value

Getters

  • db(p::Power) - Get dB attenuation value
  • watts(p::Power) - Get Watts value

Examples

julia> p1 = Power(30.0, :dB)
Power(30.0 dB, 0.001 W)

julia> db(p1), watts(p1)
(30.0, 0.001)

julia> p2 = Power(0.5, :W);

julia> round(db(p2); digits=2)
3.01

julia> db(Power(10, :W))       # integers and other numeric types work
-10.0

julia> db(Power(0.0, :W))      # zero watts is 120 dB attenuation
120.0

Conversion

Converting W to dB: -10 * log10(plW) Converting dB to W: 10^(-dB/10)

source
NMRTools.NMRBase.db — Function
db(p::Power)

Get the power level in dB attenuation.

Example

p = Power(20.0, :dB)
db(p)  # 20.0
source
NMRTools.NMRIO.FQList — Type
FQList(values, unit::Symbol, relative::Bool)
FQList(values, unit::Symbol, relative::Bool, bf, sfo)

Represents a frequency list. unit can be :Hz or :ppm, and relative indicates whether the frequency is given relative to SFO (true) or BF (false).

bf and sfo optionally record the reference base and carrier frequencies (in Hz) of the spectrometer channel this list belongs to. When present, the list can be converted to ppm or Hz on its own — without a detected frequency axis — using the single-argument ppm and hz methods. See withreference to attach a reference from a channel dictionary.

Raw values can be extracted using the data function, or (better) as absolute chemical shifts (in ppm) or relative offsets (in Hz) using ppm and hz functions.

See also: ppm, hz, withreference.

source
NMRTools.NMRIO.withreference — Function
withreference(f::FQList, channel) -> FQList

Return a copy of frequency list f with its reference base and carrier frequencies (:bf, :sfo) populated from a channel dictionary (see channels). This makes the list self-describing, so it can be converted to ppm or Hz without a detected frequency axis.

source

Samples and experiments

NMRTools.NMRBase.sample — Function
sample(nmrdata)
sample(nmrdata, keys...)

Return the sample metadata associated with the NMRData object, or nothing if not available. Sample metadata follows the schema defined at https://github.com/waudbylab/nmr-sample-schema.

When keys are provided, navigates nested dictionaries using the given keys. Keys can be strings or symbols and are automatically converted to lowercase strings for consistent access.

Examples

julia> sample(spec)
Dict{String, Any} with 6 entries:
  "nmr_tube" => Dict{String, Any}("diameter"=>"5 mm", "type"=>"regular", "sample_volume_uL"=>600)
  "buffer"   => Dict{String, Any}("solvent"=>"10% D2O", "reference_unit"=>"%w/v", "chemical_shift_reference"=>"none")
  [...]

julia> sample(spec, "notes")
"here's a note!"

julia> sample(spec, :people, :users)
1-element Vector{Any}:
 "Chris"

julia> sample(spec, "sample", "components")
2-element Vector{Any}:
 Dict{String, Any}("name" => "HEWL", "isotopic_labelling" => "unlabelled", "unit" => "mM", "concentration" => 10)
 Dict{String, Any}("name" => "gadodiamide", "isotopic_labelling" => "unlabelled", "unit" => "mM", "concentration" => 1)

julia> sample(spec, :sample, :components, :name)
2-element Vector{Any}:
 "HEWL"
 "gadodiamide"

When the final key is applied to an array (such as components), the key is mapped over each element and a filtered array is returned.

For isotopic_labelling and solvent, if the stored value is "custom", the corresponding custom_labelling or custom_solvent field is returned automatically.

See also metadata, hassample.

source
NMRTools.NMRIO.scanexperiments — Function
scanexperiments(dir; recursive=true, pdatadir=1, warn=true) -> Vector{NMRExperiment}

Scan dir for Bruker NMR experiment folders and return a vector of lightweight NMRExperiment descriptors sorted by experiment date (oldest first).

A folder is identified as a Bruker experiment if it contains an acqus file. Once identified, the scanner does not recurse into it, so pdata/ subdirectories are never misidentified as experiments.

Arguments

  • dir: Root directory to scan.
  • recursive: If true (default), search subdirectories. If false, only check immediate children of dir.
  • pdatadir: Only include experiments that have a pdata/<pdatadir>/ subdirectory, i.e. where loadnmr would succeed. Pass nothing to include all experiments regardless of whether processed data exists.
  • warn: If true (default), warn about folders that cannot be parsed.

Examples

expts = scanexperiments("/nmr/projects/lysozyme/")

# Filter with standard Julia
hsqc = filter(e -> e[:pulseprogram] == "hsqcetfpf3gpsi2", expts)
cest = filter(e -> "cest" in get(annotations(e), "experiment_type", []), expts)

# Load one
spec = loadnmr(expts[1])

See also: NMRExperiment, scansamples, findexperiments.

source
NMRTools.NMRIO.scansamples — Function
scansamples(dir; recursive=false) -> Vector{NMRSample}

Scan dir for NMR sample JSON files and return a vector of NMRSample descriptors sorted by creation timestamp. Files that cannot be parsed or have an unsupported schema version are skipped silently.

By default only the immediate directory is searched (not subdirectories), since sample files are typically stored flat in a single directory.

source
NMRTools.NMRIO.findsample — Function
findsample(expt::NMRExperiment) -> Union{NMRSample, Nothing}
findsample(expt::NMRExperiment, dir::String) -> Union{NMRSample, Nothing}
findsample(expt::NMRExperiment, candidates::Vector{NMRSample}) -> Union{NMRSample, Nothing}

Find the sample that matches expt based on experiment date falling within the sample's creation–ejection timestamp window.

  • With no second argument, searches the parent directory of the experiment folder.
  • With a directory path, searches that directory for JSON sample files.
  • With a pre-scanned Vector{NMRSample}, filters without any disk I/O.
source
NMRTools.NMRIO.findexperiments — Function
findexperiments(sample::NMRSample, dir::String; kw...) -> Vector{NMRExperiment}
findexperiments(sample::NMRSample, candidates::Vector{NMRExperiment}) -> Vector{NMRExperiment}

Find all experiments matching sample based on the experiment date falling within the sample's creation–ejection timestamp window.

  • With a directory path, calls scanexperiments(dir; kw...) then filters.
  • With a pre-scanned Vector{NMRExperiment}, filters without any disk I/O.

See also: scanexperiments, findsample.

source