From 8f8dd470041c347214dbcfd5464d1d88595c2a29 Mon Sep 17 00:00:00 2001 From: "Win Cowger, PhD" Date: Thu, 4 Jan 2024 10:11:31 -0800 Subject: [PATCH] add new function for calculating points from wavenumber windows. --- NAMESPACE | 3 +++ R/smooth_intens.R | 37 +++++++++++++++++++++++++++-- man/smooth_intens.Rd | 8 +++++++ tests/testthat/test-smooth_intens.R | 7 ++++++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index eaa3a0d6..b1fc4ab7 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -14,6 +14,8 @@ S3method(as_OpenSpecy,list) S3method(c_spec,OpenSpecy) S3method(c_spec,default) S3method(c_spec,list) +S3method(calc_window_points,OpenSpecy) +S3method(calc_window_points,default) S3method(collapse_spec,OpenSpecy) S3method(collapse_spec,default) S3method(conform_spec,OpenSpecy) @@ -71,6 +73,7 @@ export(ai_classify) export(as_OpenSpecy) export(as_hyperSpec) export(c_spec) +export(calc_window_points) export(check_OpenSpecy) export(check_lib) export(collapse_spec) diff --git a/R/smooth_intens.R b/R/smooth_intens.R index a2c4a58c..ed065cf2 100644 --- a/R/smooth_intens.R +++ b/R/smooth_intens.R @@ -16,6 +16,7 @@ #' @param polynomial polynomial order for the filter #' @param window number of data points in the window, filter length (must be #' odd). +#' @param wavenum_width the width of the window you want in wavenumbers. #' @param derivative the derivative order if you want to calculate the #' derivative. Zero (default) is no derivative. #' @param abs logical; whether you want to calculate the absolute value of the @@ -26,11 +27,17 @@ #' #' @return #' \code{smooth_intens()} returns an \code{OpenSpecy} object. -#' +#' +#' \code{calc_window_points()} returns a single numberic vector object of the +#' number of points needed to fill the window and can be passed to \code{smooth_intens()}. +#' For many applications, this is more reusable than specifying a static number of points. +#' #' @examples #' data("raman_hdpe") #' #' smooth_intens(raman_hdpe) +#' +#' smooth_intens(raman_hdpe, window = calc_window_points(x = raman_hdpe, wavenum_width = 70)) #' #' @author #' Win Cowger, Zacharias Steinmetz @@ -59,7 +66,8 @@ smooth_intens.default <- function(x, ...) { #' @rdname smooth_intens #' #' @export -smooth_intens.OpenSpecy <- function(x, polynomial = 3, window = 11, +smooth_intens.OpenSpecy <- function(x, polynomial = 3, + window = 11, derivative = 1, abs = TRUE, make_rel = TRUE, ...) { filt <- x$spectra[, lapply(.SD, .sgfilt, p = polynomial, n = window, @@ -70,6 +78,31 @@ smooth_intens.OpenSpecy <- function(x, polynomial = 3, window = 11, return(x) } +#' @export +calc_window_points <- function(x, ...) { + UseMethod("calc_window_points") +} + +#' +#' @export +calc_window_points.default <- function(x, ...) { + stop("object 'x' needs to be of class 'OpenSpecy'") +} + +#' +#' @export +calc_window_points.OpenSpecy <- function(x, wavenum_width = 70){ + raw_points <- floor(wavenum_width/spec_res(x)) + if(raw_points %% 2 == 0){ + raw_points <- raw_points - 1 + } + if(raw_points > length(x$wavenumber)){ + stop("The wavenum_width must be shorter than the full spectrum.") + } + return(raw_points) +} + + #' @importFrom signal filter sgolay .sgfilt <- function(y, p, n, m, abs = F, ...) { out <- signal::filter(filt = sgolay(p = p, n = n, m = m, ...), x = y) diff --git a/man/smooth_intens.Rd b/man/smooth_intens.Rd index 2d2fc55f..a4585d87 100644 --- a/man/smooth_intens.Rd +++ b/man/smooth_intens.Rd @@ -37,10 +37,16 @@ resulting output.} \item{make_rel}{logical; if \code{TRUE} spectra are automatically normalized with \code{\link{make_rel}()}.} +\item{wavenum_width}{the width of the window you want in wavenumbers.} + \item{\ldots}{further arguments passed to \code{\link[signal]{sgolay}()}.} } \value{ \code{smooth_intens()} returns an \code{OpenSpecy} object. + +\code{calc_window_points()} returns a single numberic vector object of the +number of points needed to fill the window and can be passed to \code{smooth_intens()}. +For many applications, this is more reusable than specifying a static number of points. } \description{ This smoother can enhance the signal to noise ratio of the data and uses a @@ -58,6 +64,8 @@ data("raman_hdpe") smooth_intens(raman_hdpe) +smooth_intens(raman_hdpe, window = calc_window_points(x = raman_hdpe, wavenum_width = 70)) + } \references{ Savitzky A, Golay MJ (1964). “Smoothing and Differentiation of Data by diff --git a/tests/testthat/test-smooth_intens.R b/tests/testthat/test-smooth_intens.R index 4f88636b..f34074c9 100644 --- a/tests/testthat/test-smooth_intens.R +++ b/tests/testthat/test-smooth_intens.R @@ -4,6 +4,13 @@ test_that("smooth_intens() handles input errors correctly", { smooth_intens(1:1000) |> expect_error() }) +test_that("calc_window_points() will return consistent values", { + calc_window_points(raman_hdpe, 70) |> expect_equal(27) + calc_window_points(raman_hdpe, 50) |> expect_equal(19) + calc_window_points(raman_hdpe, 140) |> expect_equal(55) + calc_window_points(raman_hdpe, 10000) |> expect_error() +}) + test_that("smooth_intens() works as expected", { smt <- smooth_intens(raman_hdpe, polynomial = 3) |> expect_silent()