R/calibration.R

Defines functions calibration

Documented in calibration

#' 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))
}
kimsche/MetaboMate documentation built on Aug. 8, 2020, 1:14 a.m.