Load the spant package:
Get the path to a data file included with spant:
Read the file and save to the workspace as mrs_data
:
Output some basic information about the data:
print(mrs_data)
#> MRS Data Parameters
#> ----------------------------------
#> Trans. freq (MHz) : 127.7861
#> FID data points : 1024
#> X,Y,Z dimensions : 1x1x1
#> Dynamics : 1
#> Coils : 1
#> Voxel resolution (mm) : 20x20x20
#> Sampling frequency (Hz) : 2000
#> Repetition time (s) : 2
#> Reference freq. (ppm) : 4.65
#> Nucleus : 1H
#> Spectral domain : FALSE
#> Number of transients : 128
#> Echo time (s) : 0.03
#> Manufacturer : Philips
Plot the spectral region between 5 and 0.5 ppm:
Apply a HSVD filter to the residual water region and align the spectrum to the tNAA resonance at 2.01 ppm:
Simulate a typical basis set for short TE brain analysis, print some basic information and plot:
basis <- sim_basis_1h_brain_press(mrs_proc)
print(basis)
#> Basis set parameters
#> -------------------------------
#> Trans. freq (MHz) : 127.8
#> Data points : 1024
#> Sampling frequency (Hz) : 2000
#> Elements : 27
#>
#> Names
#> -------------------------------
#> -CrCH2,Ala,Asp,Cr,GABA,Glc,Gln,
#> GSH,Glu,GPC,Ins,Lac,Lip09,
#> Lip13a,Lip13b,Lip20,MM09,MM12,
#> MM14,MM17,MM20,NAA,NAAG,PCh,
#> PCr,sIns,Tau
stackplot(basis, xlim = c(4, 0.5), labels = basis$names, y_offset = 5)
Perform ABfit analysis of the processed data
(mrs_proc
):
Plot the fit result:
Unscaled amplitudes, CRLB error estimates and other useful fitting
diagnostics, such as SNR, are given in the fit_res
results
table:
fit_res$res_tab
#> X Y Z Dynamic Coil X.CrCH2 Ala Asp Cr
#> 1 1 1 1 1 1 0 8.133812e-06 3.547061e-05 4.026722e-05
#> GABA Glc Gln GSH Glu GPC
#> 1 1.697277e-05 2.446639e-06 3.036128e-06 2.228049e-05 6.50322e-05 1.606707e-05
#> Ins Lac Lip09 Lip13a Lip13b Lip20 MM09
#> 1 5.90616e-05 5.802238e-06 2.387705e-05 2.670592e-06 0 0 9.630773e-06
#> MM12 MM14 MM17 MM20 NAA NAAG
#> 1 6.511375e-06 2.603851e-05 2.238404e-05 9.203743e-05 6.011109e-05 1.536529e-05
#> PCh PCr sIns Tau tNAA tCr tCho
#> 1 0 2.101919e-05 6.504103e-06 0 7.547638e-05 6.128641e-05 1.606707e-05
#> Glx tLM09 tLM13 tLM20 X.CrCH2.sd Ala.sd
#> 1 6.806833e-05 3.350782e-05 3.522048e-05 9.203743e-05 2.386862e-06 4.343935e-06
#> Asp.sd Cr.sd GABA.sd Glc.sd Gln.sd GSH.sd
#> 1 9.235329e-06 3.689003e-06 4.574401e-06 4.421683e-06 5.083002e-06 2.020427e-06
#> Glu.sd GPC.sd Ins.sd Lac.sd Lip09.sd Lip13a.sd
#> 1 5.082977e-06 2.602652e-06 2.093226e-06 5.301706e-06 4.119257e-06 1.328304e-05
#> Lip13b.sd Lip20.sd MM09.sd MM12.sd MM14.sd MM17.sd
#> 1 6.474469e-06 7.51091e-06 3.827554e-06 4.594029e-06 7.223427e-06 3.811302e-06
#> MM20.sd NAA.sd NAAG.sd PCh.sd PCr.sd sIns.sd
#> 1 8.595854e-06 1.017712e-06 1.208984e-06 2.236874e-06 3.084598e-06 7.240071e-07
#> Tau.sd tNAA.sd tCr.sd tCho.sd Glx.sd tLM09.sd
#> 1 3.759958e-06 7.031383e-07 5.890483e-07 2.110663e-07 3.169661e-06 1.006794e-06
#> tLM13.sd tLM20.sd phase lw shift asym
#> 1 1.573147e-06 3.01681e-06 11.10963 5.023682 -0.003765049 0.1771066
#> res.deviance res.niter res.info
#> 1 7.307673e-05 28 2
#> res.message bl_ed_pppm
#> 1 Relative error between `par' and the solution is at most `ptol'. 2.364083
#> max_bl_flex_used full_res spec_resid fit_pts ppm_range SNR
#> 1 FALSE 7.754371e-05 7.307673e-05 497 3.8 62.71686
#> SRR FQN tNAA_lw tCr_lw tCho_lw auto_bl_crit_7
#> 1 51.33278 1.492722 0.04562445 0.05189506 0.05438238 -8.900349
#> auto_bl_crit_5.901 auto_bl_crit_4.942 auto_bl_crit_4.12 auto_bl_crit_3.425
#> 1 -8.944159 -8.977354 -9.000064 -9.013367
#> auto_bl_crit_2.844 auto_bl_crit_2.364 auto_bl_crit_1.969 auto_bl_crit_1.647
#> 1 -9.02055 -9.024177 -9.023462 -9.009854
#> auto_bl_crit_1.384 auto_bl_crit_1.17 auto_bl_crit_0.997 auto_bl_crit_0.856
#> 1 -8.958654 -8.844272 -8.690746 -8.562634
#> auto_bl_crit_0.743 auto_bl_crit_0.654 auto_bl_crit_0.593 auto_bl_crit_0.558
#> 1 -8.485475 -8.44714 -8.430178 -8.423058
#> auto_bl_crit_0.54 auto_bl_crit_0.532 auto_bl_crit_0.529
#> 1 -8.42009 -8.418844 -8.418317
Note that signal names appended with “.sd” are the CRLB estimates for the uncertainty (standard deviation) in the metabolite quantity estimate. e.g. to calculate the percentage s.d. for tNAA:
Spectral SNR:
Linewidth of the tNAA resonance in PPM:
Amplitude estimates measured by the fitting method are essentially arbitrary unless scaled to a known reference signal. The simplest approach for proton-MRS is to simply divide all metabolite values by total-creatine:
fit_res_tcr_sc <- scale_amp_ratio(fit_res, "tCr")
amps <- fit_amps(fit_res_tcr_sc)
print(t(amps))
#> [,1]
#> X.CrCH2 0.00000000
#> Ala 0.13271804
#> Asp 0.57876805
#> Cr 0.65703340
#> GABA 0.27694184
#> Glc 0.03992139
#> Gln 0.04953999
#> GSH 0.36354702
#> Glu 1.06111950
#> GPC 0.26216361
#> Ins 0.96369824
#> Lac 0.09467414
#> Lip09 0.38959777
#> Lip13a 0.04357561
#> Lip13b 0.00000000
#> Lip20 0.00000000
#> MM09 0.15714370
#> MM12 0.10624502
#> MM14 0.42486606
#> MM17 0.36523659
#> MM20 1.50175935
#> NAA 0.98082254
#> NAAG 0.25071292
#> PCh 0.00000000
#> PCr 0.34296660
#> sIns 0.10612636
#> Tau 0.00000000
#> tNAA 1.23153547
#> tCr 1.00000000
#> tCho 0.26216361
#> Glx 1.11065949
#> tLM09 0.54674147
#> tLM13 0.57468668
#> tLM20 1.50175935
A more sophisticated approach to scaling metabolite values involves the use of a separate water-reference acquisition - which can be imported in the standard way:
fname_wref <- system.file("extdata", "philips_spar_sdat_W.SDAT", package = "spant")
mrs_data_wref <- read_mrs(fname_wref)
The following code assumes the voxel contains 100% white matter tissue and scales the metabolite values into molal (mM) units (mol / kg tissue water) based on the method described by Gasparovic et al MRM 2006 55(6):1219-26:
p_vols <- c(WM = 100, GM = 0, CSF = 0)
TE = 0.03
TR = 2
fit_res_molal <- scale_amp_molal_pvc(fit_res, mrs_data_wref, p_vols, TE, TR)
fit_res_molal$res_tab$tNAA
#> [1] 13.9346
An alternative method scales the metabolite values into molar (mM) units (mol / Litre of tissue) based on assumptions outlined in the LCModel manual and references therein (section 10.2). This approach may be preferred when comparing results to those obtained LCModel or TARQUIN.
fit_res_molar <- scale_amp_molar(fit_res, mrs_data_wref)
#> Warning in scale_amp_molar(fit_res, mrs_data_wref): Function name
#> (scale_amp_molar) is missleading and has been replaced with scale_amp_legacy.
fit_res_molar$res_tab$tNAA
#> [1] 6.826334
Note, while “absolute” units are attractive, a large number of assumptions about metabolite and water relaxation rates are necessary to arrive at these mM estimates. If you’re not confident at being able to justify these assumptions, scaling to a metabolite reference (eg tCr as above) is going to be a better option in most cases. Simple metabolite referenced ratios also have the benefit of being more reproducible due to the simplicity of the approach.