Skip to content

Commit

Permalink
Merge pull request #125 from wincowgerDEV/manage_spec-v1.0
Browse files Browse the repository at this point in the history
Functions for managing spectra for v1.0
  • Loading branch information
wincowgerDEV committed Jul 14, 2023
2 parents 255c5c7 + 97221ca commit 88c81d3
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 138 deletions.
6 changes: 3 additions & 3 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ S3method(as_OpenSpecy,data.frame)
S3method(as_OpenSpecy,default)
S3method(as_OpenSpecy,hyperSpec)
S3method(as_OpenSpecy,list)
S3method(conform_spec,OpenSpecy)
S3method(conform_spec,default)
S3method(conform_spec,list)
S3method(flatten_range,default)
S3method(head,OpenSpecy)
S3method(match_spec,data.frame)
Expand Down Expand Up @@ -34,9 +37,6 @@ export(collapse_particles)
export(combine_OpenSpecy)
export(conform_res)
export(conform_spec)
export(conform_spec.OpenSpecy)
export(conform_spec.default)
export(conform_spectra)
export(find_spec)
export(flatten_range)
export(gen_grid)
Expand Down
36 changes: 2 additions & 34 deletions R/adj_intens.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#' @rdname adj_intens
#'
#' @title Adjust spectral intensities to absorbance units
#'
#' @description
Expand Down Expand Up @@ -72,37 +74,3 @@ adj_intens.OpenSpecy <- function(object, type = "none", make_rel = TRUE, ...) {

return(object)
}

#' @rdname adj_intens
#'
#' @export
conform_spec <- function(object, ...) {
UseMethod("conform_spec")
}

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

#' @rdname adj_intens
#'
#' @export
conform_spec.OpenSpecy <- function(object, type = "none", make_rel = TRUE, ...) {
wn <- conform_res(object$wavenumber, ...)

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

object$wavenumber <- wn
object$spectra <- spec

adj_intens(object, type = type, make_rel = make_rel, na.rm = T)
}

.clean_spec <- function(...) {
approx(...)$y
}
63 changes: 63 additions & 0 deletions R/conform_spec.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#' @rdname conform_spec
#'
#' @title Conform spectra
#'
#' @description
#'
#'
#' @details
#' Many of
#'
#' @param x a list object of class \code{OpenSpecy}.
#' @param res spectral resolution adjusted to.
#'
#' @return
#' \code{adj_intens()} returns a data frame containing two columns
#' named \code{"wavenumber"} and \code{"intensity"}.
#'
#' @examples
#' data("raman_hdpe")
#'
#' adj_intens(raman_hdpe)
#'
#' @author
#' Win Cowger, Zacharias Steinmetz
#'
#' @seealso
#' \code{\link{subtr_bg}()} for spectral background correction;
#' \code{\link{match_spec}()} matches spectra with the Open Specy or other
#' reference libraries
#'
#' @importFrom magrittr %>%
#' @importFrom data.table .SD
#' @export
conform_spec <- function(x, res = 5) {
UseMethod("conform_spec")
}

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

#' @rdname conform_spec
#'
#' @export
conform_spec.OpenSpecy <- function(x, res = 5) {
wn <- conform_res(x$wavenumber, res = res)

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

x$wavenumber <- wn
x$spectra <- spec

return(x)
}

.conform_intens <- function(...) {
approx(...)$y
}
83 changes: 0 additions & 83 deletions R/data_norm.R
Original file line number Diff line number Diff line change
Expand Up @@ -64,89 +64,6 @@ conform_res <- function(x, res = 5) {
seq(adj_res(min(x), res, ceiling), adj_res(max(x), res, floor), by = res)
}

#' @rdname data_norm
#'
#' @export
conform_spec <- function(spec, x, xout){
c(
approx(x = x, y = spec, xout = xout)$y
)
}

#' @rdname data_norm
#'
#' @export
conform_spectra <- function(data, xout, coords = NULL){
if(is_OpenSpecy(data)){
as_OpenSpecy(
x = xout,
spectra = data$spectra[,lapply(.SD, function(x){
conform_spec(x = data$wavenumber, spec = x, xout = xout)})],
metadata = data$metadata,
coords = coords
)
}
}

#' @rdname data_norm
#'
#' @export
combine_OpenSpecy <- function(files, wavenumbers = NULL, res = NULL, coords = NULL){

if(!is.list(files)){
lof <- lapply(files, read_spec, coords = NULL)
}
else{
lof <- files
}

if(!is.null(wavenumbers)){
if(wavenumbers == "first"){
lof <- lapply(lof, function(x) {
conform_spectra(data = x,
xout = {if(!is.null(res)) conform_res(lof[[1]]$wavenumber, res = res) else lof[[1]]$wavenumber},
coords = NULL)
})
}
if(wavenumbers == "max_range"){
all = unique(unlist(lapply(lof, function(x) x$wavenumber)))
lof <- lapply(lof, function(x) {
conform_spectra(data = x,
xout = {if(!is.null(res)) conform_res(all, res = res) else all},
coords = NULL)})
}
if(wavenumbers == "min_range"){
smallest_range = which.min(vapply(lof, function(x) length(x$wavenumber), FUN.VALUE = numeric(1)))
lof <- lapply(lof, function(x) {
conform_spectra(data = x,
xout = {if(!is.null(res)) conform_res(lof[[smallest_range]]$wavenumber, res = res) else lof[[smallest_range]]$wavenumber},
coords = NULL)})
}
if(wavenumbers == "most_common_range"){
wavenumbers = table(unlist(lapply(lof, function(x) x$wavenumber)))
common_range = as.numeric(names(wavenumbers)[wavenumbers == max(wavenumbers)])
lof <- lapply(lof, function(x) {
conform_spectra(data = x,
xout = {if(!is.null(res)) conform_res(lof[[common_range]]$wavenumber, res = res) else lof[[common_range]]$wavenumber},
coords = NULL)})
}
}

unlisted <- unlist(lof, recursive = F)

list <- tapply(unlisted, names(unlisted), FUN = function(x) unname((x)))

if(length(unique(vapply(list$wavenumber, length, FUN.VALUE = numeric(1)))) > 1 & is.null(wavenumbers)){
stop("Wavenumbers are not the same between spectra, you need to specify how the wavenumbers should be merged.", call. = F)
}

as_OpenSpecy(
x = list$wavenumber[[1]],
spectra = as.data.table(list$spectra),
metadata = rbindlist(list$metadata, fill = T)
)
}

#' @rdname data_norm
#'
#' @export
Expand Down
141 changes: 141 additions & 0 deletions R/manage_spec.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#' @rdname manage_spec
#'
#' @title Manage spectral objects
#'
#' @description
#' Functions for
#'
#' @details
#' details
#'
#' @param x a list object of class \code{OpenSpecy}.
#' @param file file to be read from or written to.
#' @param share defaults to \code{NULL}; needed to share spectra with the
#' Open Specy community; see \code{\link{share_spec}()} for details.
#' @param method submethod to be used for reading text files; defaults to
#' \code{\link[data.table]{fread}()} but \code{\link[utils]{read.csv}()} works
#' as well.
#' @param \ldots further arguments passed to the submethods.
#'
#' @return
#' All \code{read_*()} functions return data frames containing two columns
#' named \code{"wavenumber"} and \code{"intensity"}.
#'
#' @examples
#' c()
#'
#' @author
#' Zacharias Steinmetz, Win Cowger
#'
#' @seealso
#' \code{\link[hyperSpec]{read.jdx}()};
#'
#' @importFrom magrittr %>%
#' @importFrom data.table data.table as.data.table fread
#' @export


#' @rdname data_norm
#'
#' @export
c_spec <- function(..., wavenumbers = NULL, res = NULL, coords = NULL){

if(!is.list(files)) {
lof <- lapply(files, read_spec, coords = NULL)
}
else{
lof <- files
}

if(!is.null(wavenumbers)){
if(wavenumbers == "first"){
lof <- lapply(lof, function(x) {
conform_spectra(data = x,
xout = {if(!is.null(res)) conform_res(lof[[1]]$wavenumber, res = res) else lof[[1]]$wavenumber},
coords = NULL)
})
}
if(wavenumbers == "max_range"){
all = unique(unlist(lapply(lof, function(x) x$wavenumber)))
lof <- lapply(lof, function(x) {
conform_spectra(data = x,
xout = {if(!is.null(res)) conform_res(all, res = res) else all},
coords = NULL)})
}
if(wavenumbers == "min_range"){
smallest_range = which.min(vapply(lof, function(x) length(x$wavenumber), FUN.VALUE = numeric(1)))
lof <- lapply(lof, function(x) {
conform_spectra(data = x,
xout = {if(!is.null(res)) conform_res(lof[[smallest_range]]$wavenumber, res = res) else lof[[smallest_range]]$wavenumber},
coords = NULL)})
}
if(wavenumbers == "most_common_range"){
wavenumbers = table(unlist(lapply(lof, function(x) x$wavenumber)))
common_range = as.numeric(names(wavenumbers)[wavenumbers == max(wavenumbers)])
lof <- lapply(lof, function(x) {
conform_spectra(data = x,
xout = {if(!is.null(res)) conform_res(lof[[common_range]]$wavenumber, res = res) else lof[[common_range]]$wavenumber},
coords = NULL)})
}
}

unlisted <- unlist(lof, recursive = F)

list <- tapply(unlisted, names(unlisted), FUN = function(x) unname((x)))

if(length(unique(vapply(list$wavenumber, length, FUN.VALUE = numeric(1)))) > 1 & is.null(wavenumbers)){
stop("Wavenumbers are not the same between spectra, you need to specify how the wavenumbers should be merged.", call. = F)
}

as_OpenSpecy(
x = list$wavenumber[[1]],
spectra = as.data.table(list$spectra),
metadata = rbindlist(list$metadata, fill = T)
)
}


#' @rdname manage_spec
#'
#' @importFrom data.table rbindlist
#' @export
# c_spec <- function(...) {
# cin <- c(...)
#
# lst <- tapply(cin, names(cin), FUN = function(x) unname((x)))
#
# as_OpenSpecy(
# x = lst$wavenumber[[1]],
# # TODO: Probably should add a check to make sure all the wavenumbers are
# # aligned before doing this.
# spectra = as.data.table(lst$spectra),
# metadata = rbindlist(lst$metadata, fill = T)
# )
# }

c_spec <- function(...) {
UseMethod("conform_spec")
}

#' @rdname conform_spec
#'
#' @export
conform_spec.default <- function(...) {
stop("'...' items need to be of class 'OpenSpecy'", call. = F)
}

#' @rdname conform_spec
#'
#' @export
conform_spec.list <- function(...) {

}

#' @rdname conform_spec
#'
#' @export
conform_spec.OpenSpecy <- function(...) {
lst <- list(...)

do.call
}
9 changes: 0 additions & 9 deletions man/adj_intens.Rd

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

Loading

0 comments on commit 88c81d3

Please sign in to comment.