Skip to content

Commit

Permalink
Improve conform_spec()
Browse files Browse the repository at this point in the history
- renamed `new_wavenumbers` argument to `range`
- updated docs
- added tests
  • Loading branch information
zsteinmetz committed Aug 16, 2023
1 parent 3a6347a commit 325e021
Show file tree
Hide file tree
Showing 15 changed files with 86 additions and 61 deletions.
6 changes: 4 additions & 2 deletions R/adj_range.R
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@
#' Win Cowger, Zacharias Steinmetz
#'
#' @seealso
#' \code{\link[base]{min}()} and \code{\link[base]{round}()};
#' \code{\link{adj_intens}()} for log transformation functions
#' \code{\link{conform_spec}()} for conforming wavenumbers to be matched with
#' a reference library;
#' \code{\link{adj_intens}()} for log transformation functions;
#' \code{\link[base]{min}()} and \code{\link[base]{round}()}
#'
#' @importFrom data.table as.data.table .SD
#' @export
Expand Down
31 changes: 18 additions & 13 deletions R/conform_spec.R
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
#' @rdname conform_spec
#'
#' @title Conform spectra to a standard wavenumber series
#'
#' @description
#' Spectra can be conformed to a standard suite of wavenumbers to be compared with a reference library or to be merged to other spectra.
#' Spectra can be conformed to a standard suite of wavenumbers to be compared
#' with a reference library or to be merged to other spectra.
#'
#' @param x a list object of class \code{OpenSpecy}.
#' @param new_wavenumbers a vector of new wavenumber values, can be just supplied as a min and max value.
#' @param range a vector of new wavenumber values, can be just supplied as a
#' min and max value.
#' @param res spectral resolution adjusted to.
#' @param \ldots further arguments passed to \code{\link[stats]{approx}()}
#'
#' @return
#' \code{adj_intens()} returns a data frame containing two columns
#' named \code{"wavenumber"} and \code{"intensity"}.
#' named \code{"wavenumber"} and \code{"intensity"}
#'
#' @examples
#' data("raman_hdpe")
Expand All @@ -21,34 +23,37 @@
#' Win Cowger, Zacharias Steinmetz
#'
#' @seealso
#' \code{\link{subtr_bg}()} for spectral background correction.
#' \code{\link{restrict_range}()} and \code{\link{flatten_range}()} for
#' adjusting wavenumber ranges;
#' \code{\link{subtr_bg}()} for spectral background correction
#'
#' @importFrom data.table .SD
#' @export
conform_spec <- function(x, new_wavenumbers, res = 5) {
conform_spec <- function(x, ...) {
UseMethod("conform_spec")
}

#' @rdname conform_spec
#'
#' @export
conform_spec.default <- function(x, new_wavenumbers, res = 5) {
conform_spec.default <- function(x, ...) {
stop("object 'x' needs to be of class 'OpenSpecy'", call. = F)
}

#' @rdname conform_spec
#'
#' @export
conform_spec.OpenSpecy <- function(x, new_wavenumbers, res = 5) {
if(is.null(new_wavenumbers)){
new_wavenumbers <- x$wavenumber
}
conform_spec.OpenSpecy <- function(x, range = NULL, res = 5, ...) {
if(is.null(range)) range <- x$wavenumber
range <- c(max(min(range), min(x$wavenumber)),
min(max(range), max(x$wavenumber))
)

wn <- conform_res(x = new_wavenumbers[new_wavenumbers <= max(x$wavenumber) & new_wavenumbers >= min(x$wavenumber)], res = res)
wn <- conform_res(range, res = res)

spec <- x$spectra[, lapply(.SD, .conform_intens,
x = x$wavenumber,
xout = wn)]
xout = wn, ...)]

x$wavenumber <- wn
x$spectra <- spec
Expand Down
4 changes: 3 additions & 1 deletion R/data_norm.R
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@
#'
#' @seealso
#' \code{\link[base]{min}()} and \code{\link[base]{round}()};
#' \code{\link{adj_intens}()} for log transformation functions
#' \code{\link{adj_intens}()} for log transformation functions;
#' \code{\link{conform_spec}()} for conforming wavenumbers of an
#' \code{OpenSpecy} object to be matched with a reference library
#'
#' @export
adj_res <- function(x, res = 1, fun = round) {
Expand Down
2 changes: 1 addition & 1 deletion R/interactive_plots.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#' plotly_spec(raman_hdpe)
#'
#' correlation <- cor_spec(
#' conform_spec(raman_hdpe, new_wavenumbers = raman_hdpe$wavenumber, res = 5),
#' conform_spec(raman_hdpe, range = raman_hdpe$wavenumber, res = 5),
#' conform_spec(tiny_map, tiny_map$wavenumbers, res = 5)
#' )
#' heatmap_spec(tiny_map, z = tiny_map$metadata$y)
Expand Down
2 changes: 1 addition & 1 deletion R/manage_spec.R
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ c_spec <- function(objects, wavenumber_transform = NULL, res = 5){
}
objects <- lapply(objects, function(x) {
conform_spec(x,
new_wavenumbers = new_wavenumbers,
range = new_wavenumbers,
res = res)})
}

Expand Down
2 changes: 1 addition & 1 deletion R/match_spec.R
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#' @examples
#' data("test_lib")
#' unknown <- read_any(read_extdata("ftir_ldpe_soil.asp")) |>
#' conform_spec(new_wavenumbers = test_lib$wavenumber,
#' conform_spec(range = test_lib$wavenumber,
#' res = spec_res(test_lib)) |>
#' process_spec()
#' matches <- cor_spec(unknown, test_lib)
Expand Down
2 changes: 1 addition & 1 deletion R/process_spec.R
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ process_spec.OpenSpecy <- function(x,
if(adj_intensity_decision)
x <- adj_intens(x, type = type, make_rel = F)
if(conform_decision)
x <- conform_spec(x, new_wavenumbers = new_wavenumbers, res = res)
x <- conform_spec(x, range = new_wavenumbers, res = res)
if(range_decision)
x <- restrict_range(x, min_range = min_range, max_range = max_range,
make_rel = F)
Expand Down
6 changes: 4 additions & 2 deletions man/adj_range.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 13 additions & 7 deletions man/conform_spec.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion man/data_norm.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/interactive_plots.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/match_spec.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 32 additions & 26 deletions tests/testthat/test-conform_spec.R
Original file line number Diff line number Diff line change
@@ -1,36 +1,42 @@
spectrum <- read_extdata("raman_hdpe.csv") |> read_any()

test_that("check that conforming spectra doesn't produce errors", {
expect_true(is_OpenSpecy(conform_spec(spectrum, c(min(spectrum$wavenumber + 10), max(spectrum$wavenumber)))))
expect_equal(conform_spec(spectrum, c(1000, 2000))$wavenumber, seq(1000, 2000, by = 5))
expect_error(is_OpenSpecy(conform_spec(spectrum, c(min(spectrum$wavenumber + 10)))))
expect_error(is_OpenSpecy(conform_spec(spectrum)))
expect_error(is_OpenSpecy(conform_spec(spectrum, c(min(spectrum$wavenumber + 10), max(spectrum$wavenumber)), res = 0)))
})
library(data.table)

data("raman_hdpe")

test_that("conform_spec.default throws an error for non-OpenSpecy objects", {
test_that("conform_spec() throws an error for non-OpenSpecy objects", {
# Create a non-OpenSpecy object
non_open_specy_object <- data.frame(wavenumber = c(1000, 1100, 1200),
intensity = c(0.1, 0.2, 0.3))
non_OpenSpecy <- data.frame(wavenumber = c(1000, 1100, 1200),
intensity = c(0.1, 0.2, 0.3))

conform_spec(non_OpenSpecy, c(1000, 2000)) |>
expect_error()
})

# Test if the function throws an error for non-OpenSpecy object
expect_error(conform_spec(non_open_specy_object, c(1000, 2000)))
test_that("conform_spec() handles errors correctly", {
conform_spec(raman_hdpe, range = c(min(raman_hdpe$wavenumber + 10),
max(raman_hdpe$wavenumber))) |>
expect_silent()
conform_spec(raman_hdpe, range = c(0,5000)) |>
expect_silent()
expect_equal(conform_spec(raman_hdpe, c(1000, 2000))$wavenumber,
seq(1000, 2000, by = 5))
conform_spec(raman_hdpe, c(min(raman_hdpe$wavenumber + 10))) |>
expect_error()
conform_spec(raman_hdpe, c(min(raman_hdpe$wavenumber + 10),
max(raman_hdpe$wavenumber)), res = 0) |>
expect_error()
})

test_that("conform_spec.OpenSpecy conforms wavenumbers correctly", {
# Create a sample OpenSpecy object
wavenumber <- seq(1000, 2000, 5)
intensity <- rnorm(length(wavenumber))
open_specy_object <- as_OpenSpecy(wavenumber, data.table(intensity = intensity))
test_that("conform_spec() conforms wavenumbers correctly", {
sam <- as_OpenSpecy(wn <- seq(1000, 2000, 5),
data.table(intensity = rnorm(length(wn))))

# Conform the wavenumbers to a new range
new_wavenumbers <- c(1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900)
conform_result <- conform_spec(open_specy_object, new_wavenumbers)
conf_spec <- conform_spec(sam, new_wavenumbers)

# Test if the wavenumber and intensity vectors have the same length after conforming
expect_equal(length(conform_result$wavenumber), length(conform_result$spectra[[1]]))
expect_equal(length(conf_spec$wavenumber), length(conf_spec$spectra[[1]]))
expect_equal(range(conf_spec$wavenumber), range(new_wavenumbers))

# Test if the wavenumber range matches the new_wavenumbers vector
expect_equal(min(conform_result$wavenumber), min(new_wavenumbers))
expect_equal(max(conform_result$wavenumber), max(new_wavenumbers))
conform_spec(raman_hdpe)$spectra$intensity[c(63, 143, 283, 325, 402)] |>
round(2) |>
expect_equal(c(78.84, 65.00, 105.73, 109.41, 116.00))
})
2 changes: 1 addition & 1 deletion tests/testthat/test-match_spec.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Create test data for cor_spec function
data("test_lib")
unknown <- read_any(read_extdata("ftir_ldpe_soil.asp")) |>
conform_spec(new_wavenumbers = test_lib$wavenumber, res = spec_res(test_lib)) |>
conform_spec(range= test_lib$wavenumber, res = spec_res(test_lib)) |>
process_spec()

# Create a subset of test_lib for filtering
Expand Down
4 changes: 2 additions & 2 deletions tests/testthat/test-workflows.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ test_that("Raman batch analysis with test library", {
expect_silent(lib <- load_lib(type = "test", path = tmp))

expect_silent(filter_spec(lib, lib$metadata$SpectrumType == "Raman"))
expect_silent(batch2 <- conform_spec(batch, new_wavenumbers = lib$wavenumber,
expect_silent(batch2 <- conform_spec(batch, lib$wavenumber,
res = spec_res(lib$wavenumber)))

expect_silent(plotly_spec(batch2))
Expand Down Expand Up @@ -48,7 +48,7 @@ test_that("Raman batch analysis with complete library", {
expect_silent(lib <- load_lib(type = "nobaseline", path = tmp))

expect_silent(filter_spec(lib, lib$metadata$SpectrumType == "Raman"))
expect_silent(batch2 <- conform_spec(batch, new_wavenumbers = lib$wavenumber,
expect_silent(batch2 <- conform_spec(batch, range = lib$wavenumber,
res = spec_res(lib$wavenumber)))

expect_silent(plotly_spec(batch2))
Expand Down

0 comments on commit 325e021

Please sign in to comment.