Skip to content

Commit

Permalink
Merge branch 'issues/114-syndata' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
ximeg committed May 27, 2020
2 parents 301467c + 68a98f9 commit 94bf154
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 46 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ hyperSpec_*.tar.gz
# Example code in package build process
*-Ex.R

# Mac files
# Mac directory files
*.DS_Store

# RStudio files
Expand Down
7 changes: 4 additions & 3 deletions hyperSpec/DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ Encoding: UTF-8
Type: Package
Title: Work with Hyperspectral Data, i.e. Spectra + Meta Information (Spatial,
Time, Concentration, ...)
Version: 0.99-20200521
Date: 2020-05-21
Version: 0.99-20200522
Date: 2020-05-22
Maintainer: Claudia Beleites <Claudia.Beleites@chemometrix.gmbh>
Authors@R: c(
person("Claudia", "Beleites", role = c("aut","cre", "dtc"), email = "Claudia.Beleites@chemometrix.gmbh"),
Expand Down Expand Up @@ -99,6 +99,7 @@ Collate:
'wl2i.R'
'extract.R'
'factor2num.R'
'fauxCell.R'
'fileio.optional.R'
'fix_spc_colnames.R'
'flu.R'
Expand Down Expand Up @@ -180,4 +181,4 @@ Collate:
'write.txt.wide.R'
'y-pastenames.R'
'zzz.R'
RoxygenNote: 7.1.0
RoxygenNote: 7.0.2
139 changes: 139 additions & 0 deletions hyperSpec/R/fauxCell.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
.fauxCell <- function() {


# Check for points inside ellipse
#
# An ellipse is a unit circle that is squeezed, rotated and translated
# -> do these transformations backwards and
# check whether points are within radius 1 of origin
# @param xy points to be checked for position inside the ellipse
# @param center center of the ellipse
# @param scale length of the main axes
# @param rot rotation angle
# @return logical indicating points inside the ellipse
in_ellipse <- function(xy, center = c(0, 0), scale = c(1, 1), a = 0,
debuglevel = 0L
) {
xy <- as.matrix(xy)
xy <- scale(xy, center = center, scale = FALSE)
xy <- xy %*% matrix(c(cos(a), -sin(a), sin(a), cos(a)), ncol = 2)
xy <- scale(xy, center = FALSE, scale = scale)

pt_in <- rowSums(xy^2) <= 1

if (debuglevel >= 1L)
plot(xy[, 1], xy[, 2], asp = 1, pch = 19, col = pt_in + 1)

## backtransformed points within unit circle?
pt_in
}

# Now for fauxCell() itself

# Create a matrix containing a faux cell image
# The matrix contains a cell which in turn contains a nucleus.
# Use ellipses to define the regions.

## 1. Set up the scanned region & needed coordinates

xy <- expand.grid(
x = seq(-11.55, 22.45, by = 1),
y = seq(-4.77, 19.23, by = 1)
)

xy$region <- "matrix"

pts_in_cell <- in_ellipse(xy[c("x", "y")],
center = c(10, 10),
scale = c(6, 10), a = -pi / 8)
xy$region[pts_in_cell] <- "cell"


pts_in_nucleus <- in_ellipse(xy[c("x", "y")],
center = c(12.5, 8),
scale = c(3, 4), a = pi / 6)
xy$region[pts_in_nucleus] <- "nucleus"

xy$region <- as.factor(xy$region)

## 2. initialize hyperSpec object

wavelength <- seq(602, 1798, by = 4)
spc <- new(
"hyperSpec",
wavelength = wavelength,
data = xy,
spc = matrix(0, nrow = nrow(xy), ncol = length(wavelength)),
label = list(spc = "intensity (arbitrary units)",
.wavelength = expression(Delta * tilde(nu) / cm^-1),
x = "x position",
y = "y position")
)

## 3. generate fake spectra

# generate "spectra" and and fill the object with copies
tmp <- 5000 * dnorm(wavelength, mean = 800, sd = 10)
spc[[spc$region == "matrix", , ]] <- rep(tmp, each = sum(spc$region == "matrix"))

tmp <- 7000 * dnorm(wavelength, mean = 1200, sd = 15)
spc[[spc$region == "cell", , ]] <- rep(tmp, each = sum(spc$region == "cell"))

tmp <- 3000 * dnorm(wavelength, mean = 1500, sd = 5)
spc[[spc$region == "nucleus", , ]] <- rep(tmp, each = sum(spc$region == "nucleus"))

# add baselines
terms <- vanderMonde(spc, order = 1)
coefs <- matrix(runif(nrow(spc) * 2), ncol = 2)
coefs <- scale(coefs, center = FALSE, scale = c(1 / 200, 1 / 30))
spc <- spc + coefs %*% terms[[]]

# generate shot noise
spc[[]] <- rpois(n = length(spc[[]]), lambda = spc[[]])

spc
}

#' Faux Cell Data Set for Testing & Demonstration
#'
#' This is a synthetic data set intended for testing and demonstration.
#'
#' The data set resembles the `chondro` data set but is entirely synthetic.
#'
#' @format The object contains 875 Raman-like spectra, allocated to three
#' groups/regions in column region: the matrix/background, the cell and the
#' cell nucleus. Each spectrum is composed of 300 data points. The spectrum
#' of each region is unique and simple, with a single peak at a particular
#' frequency and line width. Poisson noise has been added. The data is
#' indexed along the x and y dimensions, simulating data collected on a grid.
#'
#' @rdname fauxCell
#' @docType data
#' @include initialize.R
#' @export
#' @author Claudia Beleites, Bryan A. Hanson
#' @examples
#'
#' fauxCell
#'
#' plot (sample (fauxCell, 10), stacked = TRUE)
#'
#' # Plot mean spectra
#' FCgrps <- aggregate(fauxCell, fauxCell$region, mean_pm_sd)
#' plotspc(FCgrps, stacked = ".aggregate",
#' col = c("red", "green", "blue"), fill = ".aggregate")
#'
#' mapcols <- c(cell = "aquamarine", matrix = "aliceblue", nucleus = "dodgerblue")
#' plotmap(fauxCell, region ~ x * y, col.regions = mapcols)
#'
#' # PCA
#' pca <- prcomp(fauxCell)
#' plot(pca)
#'
#' loadings <- decomposition(fauxCell, t(pca$rotation), scores = FALSE)
#' plot(loadings[1 : 5], stacked = TRUE)
#'
#' plot(pca$x[,2], pca$x[,3], xlab = "PC 1", ylab = "PC 2",
#' bg = mapcols[fauxCell$region], col = "black", pch = 21)
#'
delayedAssign("fauxCell", .fauxCell())
85 changes: 43 additions & 42 deletions hyperSpec/R/vandermonde.R
Original file line number Diff line number Diff line change
@@ -1,81 +1,82 @@
##' Function evaluation on hyperSpec objects
##'
##' vandermonde generates van der Monde matrices, the hyperSpec method generates a hyperSpec object
##' containing the van der Monde matrix of the wavelengths of a hyperSpec object.
##' `vandermonde()` generates Vandermonde matrices, the hyperSpec method
##' generates a hyperSpec object containing the van der Monde matrix of the
##' wavelengths of a hyperSpec object.
##'
##' It is often numerically preferrable to map \code{wl (x)} to [0, 1], see the example.
##' It is often numerically preferrable to map `wl(x)` to \[0, 1\], see the
##' example.
##'
##' @param x object to evaluate the polynomial on
##' @param order of the polynomial
##' @md
##' @rdname vanderMonde
##' @return van der Monde matrix
##' @return Vandermonde matrix
##' @author C. Beleites
##' @export
##' @include unittest.R
vanderMonde <- function(x, order, ...) {
if (nargs() > 2) {
stop("Unknown arguments: ", names(c(...)))
}
if (nargs() > 2)
stop('Unknown arguments: ', names(c (...)))

outer(x, 0:order, `^`)
}

##' @noRd
setGeneric("vanderMonde")
setGeneric ("vanderMonde")

##' @param normalize.wl function to transorm the wavelengths before evaluating the polynomial (or
##' other function). \code{\link[hyperSpec]{normalize01}} maps the wavelength range to the interval
##' [0, 1]. Use \code{\link[base]{I}} to turn off.
##' @param ... hyperSpec method: further arguments to \code{\link{decomposition}}
##' @return hyperSpec method: hyperSpec object containing van der Monde matrix as spectra and an additional column ".vdm.order" giving the order of each spectrum (term).
##' other function). `hyperSpec::normalize01()` maps the wavelength range to the interval
##' [0, 1]. Use `base::I()` to turn off.
##' @param ... hyperSpec method: further arguments to `hyperSpec::decomposition()`
##' @return hyperSpec method: hyperSpec object containing van der Monde matrix as spectra and an additional column `$.vdm.order$ giving the order of each spectrum (term).
##' @rdname vanderMonde
##' @seealso \code{\link[hyperSpec]{wl.eval}} for calculating arbitrary functions of the wavelength,
##' @seealso `hyperSpec::wl.eval()` for calculating arbitrary functions of the wavelength,
##'
##' \code{\link[hyperSpec]{normalize01}}
##' `hyperSpec::normalize01()`
##' @export
##' @examples
##' plot (vanderMonde (flu, 2))
##' plot (vanderMonde (flu, 2, normalize.wl = I))
##' plot(vanderMonde(flu, 2))
##' plot(vanderMonde(flu, 2, normalize.wl = I))
##'
##'
setMethod("vanderMonde",
signature = signature(x = "hyperSpec"),
function(x, order, ..., normalize.wl = normalize01) {
validObject(x)

wl <- normalize.wl(x@wavelength)
setMethod("vanderMonde", signature = signature (x = "hyperSpec"),
function(x, order, ..., normalize.wl = normalize01) {
validObject (x)

x <- decomposition(x, t(vanderMonde(wl, order)), scores = FALSE, ...)
x$.vdm.order <- 0:order
x
}
)
wl <- normalize.wl(x@wavelength)

x <- decomposition(x, t(vanderMonde(wl, order)),
scores = FALSE, ...)
x$.vdm.order <- 0:order
x
})

.test(vanderMonde) <- function() {
context("vanderMonde")
.test (vanderMonde) <- function () {
context ("vanderMonde")

test_that("vector against manual calculation", {
expect_equal(
vanderMonde(c(1:3, 5), 2),
matrix(c(1, 1, 1, 1, 1, 2, 3, 5, 1, 4, 9, 25), nrow = 4)
)
expect_equal(vanderMonde(c (1:3, 5), 2),
matrix(c(1, 1, 1, 1, 1, 2, 3, 5, 1, 4, 9, 25), nrow = 4))
})

test_that("default method doesn't provide normalization", {
expect_error(vanderMonde(1, 0, normalize.wl = normalize01))
})

test_that("hyperSpec objects", {
expect_true(chk.hy(vanderMonde(flu, 0)))
expect_true(validObject(vanderMonde(flu, 0)))
expect_true(chk.hy (vanderMonde (flu, 0)))
expect_true(validObject (vanderMonde (flu, 0)))

tmp <- vanderMonde(paracetamol, 3, normalize.wl = I)
dimnames(tmp$spc) <- NULL
expect_equal(tmp [[]], t(vanderMonde(wl(paracetamol), 3)))
tmp <- vanderMonde (paracetamol, 3, normalize.wl = I)
dimnames (tmp$spc) <- NULL
expect_equal (tmp [[]], t (vanderMonde (wl (paracetamol), 3)))

tmp <- vanderMonde(paracetamol, 3, normalize.wl = normalize01)
dimnames(tmp$spc) <- NULL
expect_equal(tmp[[]], t(vanderMonde(normalize01(wl(paracetamol)), 3)))
tmp <- vanderMonde (paracetamol, 3, normalize.wl = normalize01)
dimnames (tmp$spc) <- NULL
expect_equal (tmp[[]], t (vanderMonde (normalize01 (
wl (paracetamol)
), 3)))
})
}


0 comments on commit 94bf154

Please sign in to comment.