## Methods for xcmsRaw classes.
####============================================================
## msSlice
##
## Extract an MSslice object from the xcmsRaw object. This MSslice
## contains (one or more) MSdata objects.
setMethod("msSlice", "xcmsRaw",
function(object, mzrange=NULL, rtrange=NULL, ...){
call <- match.call()
## Get the data from the raw object.
## We'll call the msData
res <- msData(object, mzrange=mzrange, rtrange=rtrange, ...)
if(is(res, "MSdata")){
return(msSlice(res))
}else{
return(MSsliceList(lapply(res, MSslice)))
## Got a list of objects, return a MSsliceList.
}
})
####============================================================
## msMap
##
## Gets either the full or a subset of the profile matrix as
## MSmap object (defined in MSnbase), i.e. a two dimensional
## matrix m/z against retention time, the values being the intensities
## measured for each mz rt tuple.
####------------------------------------------------------------
setMethod("msMap", "xcmsRaw",
function(object, mzrange=NULL, rtrange=NULL, intrange=NULL,
resMz=0.005, zeroIsNA=FALSE, ...){
call <- match.call()
datmat <- getData(x=object, mzrange=mzrange, rtrange=rtrange,
intrange=intrange)
if(is(datmat, "list")){
res <- lapply(datmat, function(z){
return(.matrix2msmap(z, resMz=resMz, zeroIsNA=zeroIsNA,
call=call))
})
}else{
res <- .matrix2msmap(datmat, resMz=resMz, zeroIsNA=zeroIsNA,
call=call)
}
return(res)
})
## The internal working fun... assumes that x is a matrix with
## columns time, mz and intensity such as the one returned by getData.
.matrix2msmap <- function(x, resMz=0.005, zeroIsNA=TRUE, call=match.call()){
mzr <- range(x[, "mz"])
minM <- round(mzr[1]/resMz) * resMz
maxM <- round(mzr[2]/resMz) * resMz
numC <- (maxM - minM) / resMz + 1
## Calculating scnIdx, i.e. the index (0-based) in which the retention
## time changes.
rl <- runLength(Rle(x[, "time"]))
scnIdx <- c(0, cumsum(rl)[-length(rl)])
mat <- xcms:::profBinM(x[, "mz"], x[, "intensity"], scnIdx, numC,
minM, maxM, FALSE, list())
msm <- new("MSmap", call=call, map=t(mat), rt=unique(x[, "time"]),
mz=seq(minM, maxM, length.out=numC), t=FALSE)
return(msm)
}
####============================================================
## msData
##
## Extract MS data from an xcmsRaw object for one or more specified
## rt and/or mz ranges
####------------------------------------------------------------
setMethod("msData", "xcmsRaw",
function(object, mzrange=NULL, rtrange=NULL, ...){
## Do input argument checking:
## mzrange and rtrange can be numeric of length 2.
haverows <- unique(c(nrow(mzrange), nrow(rtrange)))
call <- match.call()
gotMatrix <- FALSE
if(length(haverows) > 1)
stop("If 'mzrange' and 'rtrange' are matrices they have to",
" have the same number of rows!")
if(is.null(mzrange) & is.null(rtrange)){
message("Both 'mzrange' and 'rtrange' are NULL, returning the full data.")
}else{
if(!is.null(mzrange)){
if(is(mzrange, "matrix")){
## Then rtrange has to NULL or a matrix
if(!is.null(rtrange)){
if(!is(rtrange, "matrix"))
stop("If 'mzrange' is a matrix, also 'rtrange', if not NULL,",
" has to be a matrix!")
}
gotMatrix <- TRUE
if(ncol(mzrange) != 2){
stop("'mzrange' is supposed to be either a numeric of",
" length 2 or a matrix with two columns!")
}
}
}
if(!is.null(rtrange)){
if(is(rtrange, "matrix")){
## Then rtrange has to NULL or a matrix
if(!is.null(mzrange)){
if(!is(mzrange, "matrix"))
stop("If 'rtrange' is a matrix, also 'mzrange', if not NULL,",
" has to be a matrix!")
}
gotMatrix <- TRUE
if(ncol(rtrange) != 2){
stop("'rtrange' is supposed to be either a numeric of",
" length 2 or a matrix with two columns!")
}
}
}
}
## Done, now we can proceed to the function.
if(!gotMatrix){
## Just get the data.
res <- .doGetMSdata(object, mzrange=mzrange, rtrange=rtrange, ...)
return(res)
}else{
## A little more to do...
## We want to split the ranges
## into a list (of lists) and run a lapply on that list element.
## Note, funnily enough I can call NULL[1, ] and get NULL.
arglist <- vector("list", length=haverows)
sct <- scantimes(object)
for(i in 1:haverows){
arglist[[i]] <- list(mzrange=mzrange[i, ],
rtrange=rtrange[i, ])
}
res <- lapply(arglist, function(z){
return(.doGetMSdata(object, mzrange=z$mzrange,
rtrange=z$rtrange, sct=sct))
})
return(res)
}
})
## The workhorse.
.doGetMSdata <- function(x, sct=NULL, mzrange=NULL, rtrange=NULL, intrange=NULL){
if(is.null(sct))
sct <- scantimes(x)
## Return the full blown matrix if no subsetting is done.
if(is.null(mzrange) & is.null(rtrange) & is.null(intrange)){
return(MSdata(mz=x@env$mz, rtime=sct, intensity=x@env$intensity))
}else{
returnMe <- -9
## Subset based on mzrange
if(!is.null(mzrange)){
if(length(mzrange) != 2)
stop("'mzrange' has to be a numeric vector of length 2.")
mzrange <- sort(mzrange)
returnMe <- which(x@env$mz >= mzrange[1] & x@env$mz <= mzrange[2])
## Return an empty matrix if we can not find any of these.
if(length(returnMe) == 0)
return(MSdata(rtime=numeric(), mz=numeric(), intensity=numeric()))
}
## Subset based on rtrange
if(!is.null(rtrange)){
if(length(rtrange) != 2)
stop("'rtrange' has to be a numeric vector of length 2.")
rtrange <- sort(rtrange)
returnMeRt <- which(sct >= rtrange[1] & sct <= rtrange[2])
if(length(returnMeRt) == 0)
return(MSdata(rtime=numeric(), mz=numeric(), intensity=numeric()))
if(returnMe[1] > 0){
returnMe <- intersect(returnMe, returnMeRt)
}else{
returnMe <- returnMeRt
}
## Return an empty matrix if we can not find any of these.
if(length(returnMe) == 0)
return(MSdata(rtime=numeric(), mz=numeric(), intensity=numeric()))
}
## Subset based on intrange
if(!is.null(intrange)){
if(length(intrange) != 2)
stop("'intrange' has to be a numeric vector of length 2.")
intrange <- sort(intrange)
returnMeRt <- which(x@env$intensity >= intrange[1] & x@env$intensity <= intrange[2])
if(length(returnMeRt) == 0)
return(MSdata(rtime=numeric(), mz=numeric(), intensity=numeric()))
if(returnMe[1] > 0){
returnMe <- intersect(returnMe, returnMeRt)
}else{
returnMe <- returnMeRt
}
}
return(MSdata(mz=x@env$mz[returnMe],
rtime=sct[returnMe],
intensity=x@env$intensity[returnMe]))
}
}
####============================================================
## getData
##
## Get a matrix with the raw data, i.e. retention time, mz and
## intensity. Allows to optionally define subsets of the data.
setMethod("getData", signature(x="xcmsRaw", mzrange="NumericOrNull",
rtrange="NumericOrNull",
intrange="NumericOrNull"),
function(x, mzrange=NULL, rtrange=NULL, intrange=NULL){
return(.doGetData(x, mzrange=mzrange, rtrange=rtrange,
intrange=intrange))
})
## The same method but with multiple ranges.
setMethod("getData", signature(x="xcmsRaw", mzrange="MatrixOrNull",
rtrange="MatrixOrNull",
intrange="MatrixOrNull"),
function(x, mzrange=NULL, rtrange=NULL, intrange=NULL){
if(!is.null(mzrange) | !is.null(rtrange) | !is.null(intrange)){
## Check input arguments:
haverows <- unique(c(nrow(mzrange), nrow(rtrange), nrow(intrange)))
if(length(haverows) > 1)
stop("If specified, 'mzrange', 'rtrange' and 'intrange' have to",
" have the same number of rows!")
if(!is.null(mzrange)){
if(ncol(mzrange) != 2)
stop("'mzrange' is supposed to be either a numeric of",
" length 2 or a matrix with two columns!")
}
if(!is.null(rtrange)){
if(ncol(rtrange) != 2)
stop("'rtrange' is supposed to be either a numeric of",
" length 2 or a matrix with two columns!")
}
if(!is.null(intrange)){
if(ncol(intrange) != 2)
stop("'intrange' is supposed to be either a numeric of",
" length 2 or a matrix with two columns!")
}
## Finally done; now we can proceed. We want to split the ranges
## into a list (of lists) and run a lapply on that list element.
## Note, funnily enough I can call NULL[1, ] and get NULL.
arglist <- vector("list", length=haverows)
for(i in 1:haverows){
arglist[[i]] <- list(mzrange=mzrange[i, ],
rtrange=rtrange[i, ],
intrange=intrange[i, ])
}
res <- lapply(arglist, function(z){
return(.doGetData(x, mzrange=z$mzrange,
rtrange=z$rtrange,
intrange=z$intrange))
})
return(res)
}else{
## Well, all arguments are NULL, just call the function.
return(.doGetData(x, mzrange=mzrange, rtrange=rtrange,
intrange=intrange))
}
})
## The workhorse.
.doGetData <- function(x, sct=NULL, mzrange=NULL, rtrange=NULL, intrange=NULL){
if(is.null(sct))
sct <- scantimes(x)
## Return the full blown matrix if no subsetting is done.
if(is.null(mzrange) & is.null(rtrange) & is.null(intrange)){
return(cbind(time=sct, mz=x@env$mz, intensity=x@env$intensity))
}else{
returnMe <- -9
## Subset based on mzrange
if(!is.null(mzrange)){
if(length(mzrange) != 2)
stop("'mzrange' has to be a numeric vector of length 2.")
mzrange <- sort(mzrange)
returnMe <- which(x@env$mz >= mzrange[1] & x@env$mz <= mzrange[2])
## Return an empty matrix if we can not find any of these.
if(length(returnMe) == 0)
return(cbind(time=numeric(), mz=numeric(), intensity=numeric()))
}
## Subset based on rtrange
if(!is.null(rtrange)){
if(length(rtrange) != 2)
stop("'rtrange' has to be a numeric vector of length 2.")
rtrange <- sort(rtrange)
returnMeRt <- which(sct >= rtrange[1] & sct <= rtrange[2])
if(length(returnMeRt) == 0)
return(cbind(time=numeric(), mz=numeric(), intensity=numeric()))
if(returnMe[1] > 0){
returnMe <- intersect(returnMe, returnMeRt)
}else{
returnMe <- returnMeRt
}
## Return an empty matrix if we can not find any of these.
if(length(returnMe) == 0)
return(cbind(time=numeric(), mz=numeric(), intensity=numeric()))
}
## Subset based on intrange
if(!is.null(intrange)){
if(length(intrange) != 2)
stop("'intrange' has to be a numeric vector of length 2.")
intrange <- sort(intrange)
returnMeRt <- which(x@env$intensity >= intrange[1] & x@env$intensity <= intrange[2])
if(length(returnMeRt) == 0)
return(cbind(time=numeric(), mz=numeric(), intensity=numeric()))
if(returnMe[1] > 0){
returnMe <- intersect(returnMe, returnMeRt)
}else{
returnMe <- returnMeRt
}
}
return(cbind(time=sct[returnMe],
mz=x@env$mz[returnMe],
intensity=x@env$intensity[returnMe]))
}
}
####============================================================
## scantimes
##
## Returns a vector with the retention time for the individual
## measured mz values.
####------------------------------------------------------------
setMethod("scantimes", "xcmsRaw", function(x){
return(rep.int(x@scantime, times=diff(c(x@scanindex, length(x@env$mz)))))
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.