#' Spectral calibration to a chemical shift reference
#' @export
#' @aliases calibration
#' @description Spectral calibration to a chemical shift reference.
#' @param NMR Input NMR matrix with rows representing spectra and columns representing chemical shifts.
#' @param ppm ppm vector with the same length as \code{ncol(X)}.
#' @param type Either 'Urine' or 'Plasma' for urine or blood-derived spectra, respectively (see Details).
#' @details Spectral calibration to a chemical shift reference. If \code{type='Urine'} calibration will be performed using signal resonating around 0 ppm (Trimethylsilylpropanoic acid resonance). If \code{type='Plasma'}, the doublet around 5.23, originating from the alpha anomer of glucose, will be used for calibration. \strong{Blood serum-derived spectra} can also be calibrated with input argument \code{type='Plasma'}.
#' @return Returned is the calibrated NMR data matrix.
#' @references Dona, A.C., \emph{et al.} (2014) Precision high-throughput proton NMR spectroscopy of human urine, serum, and plasma for large-scale metabolic phenotyping. \emph{Analytical Chemistry}. 86.19. 9887-94.
#' @seealso \code{\link{readBruker}}
#' @author Torben Kimhofer \email{tkimhofer@@gmail.com}
#' @importFrom speaq detectSpecPeaks
### function shiftes the max TSP intensity to zero
calibration <- function(NMR, ppm, type = "Urine") {
# function get indices in ppm which match the specified range
get.idx <- function(range = c(1, 5), ppm) {
range <- sort(range, decreasing = T)
which(ppm <= range[1] & ppm >= range[2])
}
if (class(type[1]) == "numeric") {
idx <- get.idx(c(type[1:2]), ppm)
zero.ppm <- which.min(abs(ppm[idx] - type[3]))
maxInt <- array()
for (i in 1:nrow(NMR)) {
maxInt[i] <- which.max(NMR[i, idx])
}
} else {
if (type == "Urine") {
idx <- get.idx(c(-0.2, 0.2), ppm)
zero.ppm <- which.min(abs(ppm[idx]))
maxInt <- array()
for (i in 1:nrow(NMR)) {
maxInt[i] <- which.max(NMR[i, idx])
}
}
if (type == "Plasma") {
idx <- get.idx(c(5.1, 5.3), ppm)
zero.ppm <- which.min(abs(5.233 - (ppm[idx])))
# perform peak picking (squaq, inlcluding noise estimation) find two signals that have a certain distance and are close to 5.233
source("/Users/tk2812/Box Sync/R_scr/fct_pqn.R")
tt <- noise.est(NMR, ppm, where = c(14.4, 14.5))
ppm1 <- ppm[idx]
X1 <- NMR[, idx]
res <- list()
for (i in 1:nrow(X1)) {
res[[i]] <- detectSpecPeaks(t(matrix(X1[i, ])), baselineThresh = tt[i] * 4)
}
ics <- list()
for (i in 1:nrow(X1)) {
idx <- which(diff(res[[i]][[1]]) > 39 & diff(res[[i]][[1]]) < 44)
if (length(idx) > 1) {
distGluc <- array()
for (j in 1:length(idx)) {
distGluc[j] <- mean(ppm1[res[[i]][[1]][idx[j]]:res[[i]][[1]][idx[j] + 1]])
}
id <- which.min(abs(distGluc - 5.233))
ics[[i]] <- res[[i]][[1]][idx[id]:(idx[id] + 1)]
} else {
ics[[i]] <- res[[i]][[1]][idx:(idx + 1)]
}
}
if (length(which(sapply(ics, length) > 2)) > 0) {
stop("Something went wrong!")
}
maxInt <- sapply(ics, "[[", 1)
}
}
Int.corr <- zero.ppm - maxInt
# if Int.corr<0: shift is > zero
for (i in 1:nrow(NMR)) {
x <- NMR[i, ]
if (Int.corr[i] < 0) {
x <- c(x[-c(1:abs(Int.corr[i]))], rep(0, abs(Int.corr[i])))
}
if (Int.corr[i] > 0) {
x <- c(rep(0, abs(Int.corr[i])), x)
}
NMR[i, ] <- x[1:length(ppm)]
}
return((NMR))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.