#
# This file contains methods for importing and conditioning APT data
#
#### Load Data ####
### readPOS ###
#' Read a POS File
#'
#' \code{readPOS} reads a POS file (from IVAS) into a `data.frame`.
#'
#' @param filepath Character. The file path to the POS file.
#' @return A `data.frame` with columns corresponding to the x, y, and z
#' positions of the reconstruction and the mass-to-charge ratio.
#'
#' @references Larson *et al.*,
#' *Local Electrode Atom Probe Tomography: A User's Guide* (2009)
#' @family APT import functions
#'
#' @export
readPOS <- function(filepath) {
pos.len <- file.info(filepath)["size"] / 4
pos.len <- as.numeric(pos.len)
pos.raw <- readBin(
filepath,
what = "numeric",
size = 4, endian = "big", n = pos.len
)
pos.mat <- matrix(pos.raw, ncol = 4, byrow = T)
pos.dat <- as.data.frame(pos.mat)
names(pos.dat) <- c("x", "y", "z", "mass")
pos.name <- sub("\\.pos$", "", basename(filepath), ignore.case = TRUE)
attr(pos.dat, "metaData") <- list(
name = pos.name
)
return(pos.dat)
}
### readATO ###
#' Read an ATO File
#'
#' \code{readATO} reads an ATO file (from IVAS) into a `data.frame`.
#'
#' @param filepath Character. The file path to the ATO file.
#' @return A `data.frame` with columns corresponding to the ATO structure
#' definition.
#'
#' @references Larson *et al.*,
#' *Local Electrode Atom Probe Tomography: A User's Guide* (2009)
#' @family APT import functions
#'
#' @export
readATO <- function(filepath) {
ato.len <- file.info(filepath)["size"] / 4
ato.len <- as.numeric(ato.len)
ato.file <- file(filepath, open = "rb")
seek(ato.file, where = 8)
ato.raw <- readBin(
ato.file,
what = "numeric",
size = 4, endian = "little", n = ato.len
)
ato.mat <- matrix(ato.raw, ncol = 14, byrow = T)
ato.dat <- as.data.frame(ato.mat)
names(ato.dat) <- c(
"x", "y", "z", "mass", "clusID", "pIndex", "Vdc",
"TOF", "dx", "dy", "Vp", "shank", "FouR", "FouI"
)
ato.name <- sub("\\.ato$", "", basename(filepath), ignore.case = TRUE)
attr(ato.dat, "metaData") <- list(
name = ato.name
)
close(ato.file)
return(ato.dat)
}
### readRRNG ###
#' Read an RRNG File
#'
#' \code{readRRNG} reads an RRNG file from IVAS into an RNG object for ranging
#' a \code{\link[MALDIquant:MassSpectrum-class]{MassSpectrum}} generated by
#' \code{\link{createSpec}}
#'
#' @param filepath Character. A filepath to the RRNG file.
#' @return A `data.frame` with columns corresponding to the mass ranges,
#' ion volume, name, molecular formulae (`NA` if not present), and color
#' for display.
#'
#' @references Larson *et al.*,
#' *Local Electrode Atom Probe Tomography: A User's Guide* (2009)
#' @family APT import functions
#'
#' @export
readRRNG <- function(filepath) {
text <- readLines(filepath, warn = FALSE)
n <- grep("Number=", text, value = TRUE)
n <- strsplit(n, "=")
n <- sapply(n, function(m) {
as.numeric(m[2])
})
elem <- strsplit(text[1:n[1] + 2], "=")
elem <- sapply(elem, function(m) {
m[2]
})
r.pos <- grep("[Ranges]", text, fixed = TRUE)
entries <- sub("^Range[[:digit:]]+=", "", text[-(1:(r.pos + 1))])
entries <- strsplit(entries, " ")
dat <- lapply(entries, function(X) {
mass.start <- as.numeric(X[1])
mass.end <- as.numeric(X[2])
mass.volume <- as.numeric(sub("Vol:", "", X[3]))
mass.name <- sapply(elem, function(el) {
m <- paste0(el, ":")
w <- grepl(m, X)
if (any(w)) {
n <- sub(":", "", X[w])
} else {
n <- NA
}
return(n)
})
mass.name <- na.omit(mass.name)
mass.name <- paste0(mass.name, collapse = "")
data("isotopes", package = "enviPat", envir = environment())
form.warn <- enviPat::check_chemform(isotopes, mass.name)[, 1]
mass.formula <- mapply(function(name, warn) {
if (warn) {
NA
} else {
name
}
}, mass.name, form.warn)
mass.color <- sub("Color:", "#", tail(X, n = 1))
data.frame(
start = mass.start,
end = mass.end,
volume = mass.volume,
name = mass.name,
formula = mass.formula,
color = mass.color,
stringsAsFactors = FALSE
)
})
dat <- do.call(rbind, dat)
rownames(dat) <- NULL
rng.name <- sub("\\.rrng$", "", basename(filepath), ignore.case = TRUE)
attr(dat, "metaData") <- list(
name = rng.name
)
return(dat)
}
#### Transform Data ####
### createSpat ###
#' Create a pp3 from a POS or ATO
#'
#' \code{createSpat} creates a \code{\link[spatstat.geom]{pp3}} from a POS or ATO
#' data frame.
#'
#' @param pos A POS or ATO data frame.
#' @param win The domain of the data.
#' @return A \code{\link[spatstat.geom]{pp3}} with the x,y,z positions of the hits in
#' the supplied POS or ATO.
#'
#' @family APT data transformation functions
#'
#' @seealso \code{\link{readPOS}}, \code{\link{readATO}},
#' \code{\link[spatstat.geom]{pp3}}
#'
#' @export
createSpat <- function(pos, win = NULL, marks = NULL) {
pp3.box <- win
if (is.null(win)) {
pp3.box <- sapply(pos[1:3], range)
}
pp3.dat <- spatstat.geom::pp3(pos$x, pos$y, pos$z, pp3.box, marks = marks)
pp3.dat <- pp3.dat[spatstat.geom::inside.boxx(pp3.dat, w = pp3.box)]
attr(pp3.dat, "metaData") <- attr(pos, "metaData")
return(pp3.dat)
}
### createDet ###
#' Create a "ppp" from an ATO.
#'
#' `createDet` generates a \code{\link[spatstat.geom]{ppp}} of detector hits from an
#' ATO.
#'
#' @param ato An ATO data frame.
#' @param window An object of class \code{\link[spatstat.geom]{owin}}. If `NULL` (the
#' default), a window will be calculated from the data using
#' \code{\link[spatstat.geom]{ripras}}.
#' @return A \code{\link[spatstat.geom]{ppp}} with the positions of the detector hits
#' from the ATO.
#'
#' @family APT data transformation functions
#'
#' @seealso \code{\link{readATO}}, \code{\link[spatstat.geom]{ppp}},
#' \code{\link[spatstat.geom]{ripras}}
#'
#' @export
createDet <- function(ato, win = NULL, marks = NULL) {
if (is.null(win)) {
win <- spatstat.geom::ripras(ato$dx, ato$dy)
unitname(win) <- "cm"
}
det.dat <- spatstat.geom::ppp(ato$dx, ato$dy, window = win, marks = marks)
attr(det.dat, "metaData") <- attr(ato, "metaData")
return(det.dat)
}
### createSpec ###
#' Create a \code{\link[MALDIquant:MassSpectrum-class]{MassSpectrum}} from a POS
#' or ATO
#'
#' `createSpec` generates a
#' \code{\link[MALDIquant:MassSpectrum-class]{MassSpectrum}} object with a
#' specified resolution from an ATO or POS data frame (like that created by
#' \code{\link{readPOS}}).
#'
#' @param pos A POS or ATO data frame.
#' @param res numeric. The bin width of the mass spectrum.
#' @param clip numeric of length two. The minimum and maximum mass values to be
#' included in the mass spectrum. If `NULL` (the default), all values are
#' included.
#'
#' @return A \code{\link[MALDIquant:MassSpectrum-class]{MassSpectrum}} from the
#' `mass` field of the POS or ATO, with the resolution set by `res`.
#'
#' @details
#' The input POS or ATO is binned by mass values; the `res` parameter sets
#' the width of the mass bins used in \code{\link[graphics]{hist}} to create the
#' input to the \code{\link[MALDIquant]{createMassSpectrum}} call, and also acts
#' as a tolerance around the spectrum minimum and maximum mass. The minimum of
#' the mass value is zero unless `clip` is set.
#'
#' @family APT data transformation functions
#'
#' @seealso \code{\link{readPOS}}, \code{\link{readATO}},
#' \code{\link[MALDIquant:MassSpectrum-class]{MassSpectrum}}
#'
#' @export
createSpec <- function(pos, res = 0.05, clip = NULL) {
m <- pos$mass
if (is.numeric(clip) & length(clip) == 2) {
m <- m[m >= clip[1] & m <= clip[2]]
}
ms.max <- ceiling(max(m) / res) * res
ms.min <- floor(min(m) / res) * res
ms.breaks <- seq(ms.min, ms.max, res)
ms.hist <- hist(m, ms.breaks, plot = F)
ms.dat <- MALDIquant::createMassSpectrum(
ms.hist$mids[-1], ms.hist$counts[-1],
metaData = attr(pos, "metaData")
)
return(ms.dat)
}
#### Write Data ####
### writePOS ###
#' Write a POS File
#'
#' `writePOS` writes a POS `data.frame` into a POS file
#'
#' @param pos A `data.frame` with columns of x, y, z, and mass, following the
#' structure of the `data.frame` returned by \code{\link{readPOS}}.
#' @param filepath A string. The file path to the `POS` file.
#' @return `NULL`
#'
#' @references Larson `et al.`,
#' `Local Electrode Atom Probe Tomography: A User's Guide` (2009)
#' @seealso \code{\link{readPOS}}
#'
#' @export
writePOS <- function(pos, filepath) {
p.mat <- as.matrix(pos)
p.vec <- as.numeric(t(p.mat))
writeBin(p.vec, filepath, size = 4, endian = "big")
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.