diff --git a/DESCRIPTION b/DESCRIPTION index 742f7d3..0001f45 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: MassTools Title: R package for mass and molecular formula calculations -Version: 0.2.11 +Version: 0.2.12 Authors@R: person("Maximilian", "Helf", email = "maximilian.helf@gmail.com", role = c("cre", "aut"), comment = c(ORCID = "0000-0002-1393-3999")) biocViews: MassSpectrometry, Cheminformatics Description: Provides heuristic filters for molecula formulas calculated with Rdisop and simple formatting functions for molecular formulas. diff --git a/R/Functions_Spectra.R b/R/Functions_Spectra.R index 94a28d4..4417245 100644 --- a/R/Functions_Spectra.R +++ b/R/Functions_Spectra.R @@ -23,7 +23,7 @@ #' if \code{speclist} is a \code{Spectra} object or #' a \code{list} of \code{Spectrum} objects: returns a \code{Spectrum} object. #' if \code{speclist} is a \code{matrix} object or -#' a \code{list} of \code{matrix} objects: returns a \code{Spectrum} object. +#' a \code{list} of \code{matrix} objects: returns a \code{matrix} object. #' #' @export mergeMS <- function(speclist, ppm =5, mzdiff = 0.0005, diff --git a/R/Functions_Spectra_comparison.R b/R/Functions_Spectra_comparison.R index 3ddaf6f..cc9d922 100644 --- a/R/Functions_Spectra_comparison.R +++ b/R/Functions_Spectra_comparison.R @@ -1,3 +1,36 @@ +#' cosine2 +#' +#' simple cosine calculation +#' +#' @param x numeric vector 1 +#' @param y numeric vector 2 +#' +#' @return cosine between two numeric vectors of equal length +#' +#' +cosine <- function(x,y){ + + sum(x * y)/(sqrt(sum(x * x)) * sqrt(sum(y * y))) + +} + +#' spectralAngle +#' +#' Calculate spectral angle +#' +#' @param x numeric vector 1 +#' @param y numeric vector 2 +#' +#' @return spectral angle score between two numeric vectors of equal length +#' +#' +spectralAngle <- function(x,y){ + + 1 - ((2*acos(cosine(x,y)))/pi) + +} + + #' pairCompare #' #' Compare two vectors of equal length pairwise and calculate a similarity @@ -7,16 +40,16 @@ #' @param v1 vector 1 #' @param v2 vector 2 #' @param NAasZero replace NA values with 0 if the value is NA in one vector, but not the other -#' @param method "cosine" will use lsa::cosine(), "pearson" will use stats::cor() +#' @param method "cosine" will use MassTools::cosine(), "pearson" will use stats::cor() #' #' @importFrom stats cor -#' @importFrom lsa cosine #' #' @return the result of the method call, a numeric similarity score #' pairCompare <- function(v1, v2, NAasZero = T, method = c("cosine", "pearson", - "kendall", "spearman")){ + "kendall", "spearman", + "spectralAngle")){ #remove instances where values in both vectors are NA remfeats <- is.na(v1) & is.na(v2) @@ -42,7 +75,9 @@ pairCompare <- function(v1, v2, NAasZero = T, } if(method[1] == "cosine"){ - cosine(matrix(c(v1,v2),ncol = 2, byrow = F))[1,2] + cosine(v1,v2) + }else if(method[1] == "spectralAngle"){ + spectralAngle(v1,v2) }else{ cor(v1,v2, method = method[1], use = "pairwise.complete.obs") } @@ -63,7 +98,7 @@ pairCompare <- function(v1, v2, NAasZero = T, #' has to be Parent(spec2) - Parent(spec1) ) to find alternative matches / #' neutral loss matches; will only be calculated if \code{abs(parentshift) > abs(mztol)} #' @param method method passed on to \code{\link{pairCompare}()}; -#' "cosine" will use lsa::cosine(), "pearson" will use stats::cor() +#' "cosine" will use MassTools::cosine(), "pearson" will use stats::cor() #' @param minpeaks minimum number #' of peaks that have to be matched, otherwise returns 0 #' @param nonmatched if TRUE, will add non-matching peaks to calculation, @@ -149,7 +184,7 @@ network1 <- function(spec1, spec2, #' @param speclist (non-nested) list of MS spectra #' @param parentmasses vector of parent m/z values (same length as speclist). #' @param mztol max difference between matched peaks in m/z -#' @param method "cosine" will use lsa::cosine(), "pearson" will use stats::cor() +#' @param method "cosine" will use MassTools::cosine(), "pearson" will use stats::cor() #' @param minpeaks minimum number of peaks that have to be matched, otherwise returns 0 #' @param nonmatched if TRUE, will add non-matching peaks to calculation, #' with 0 intensity in the spectrum missing the peak @@ -181,6 +216,7 @@ makeEdges <- function(speclist, selectlist[[i]] <- i:length(speclist) } + p20 <- ceiling(length(selectlist)/20) if(!is.null(parentmasses)){ parentmasses <- parentmasses[selNonNulls] @@ -192,7 +228,9 @@ makeEdges <- function(speclist, } - alledges <- mapply(function(sel, specs, pmasses){ + alledges <- mapply(function(n, specs, pmasses){ + if(!n%%p20){message(paste((n/p20)*5, "% done"))} + sel <- selectlist[[n]] mapply(network1, spec1 = specs[sel[-1]], parentshift = pmasses, MoreArgs = list(spec2 = specs[[sel[1]]], mztol = mztol, @@ -200,14 +238,17 @@ makeEdges <- function(speclist, method = method, nonmatched = nonmatched)) }, - sel = selectlist, + n = seq_len(length(selectlist)), pmasses = pmassShifts, MoreArgs = list(specs = speclist), SIMPLIFY = F) }else{ - alledges <- lapply(selectlist, function(sel, specs, mzt, mp, nonm){ + alledges <- lapply(seq_len(length(selectlist)), + function(n, specs, mzt, mp, nonm){ + if(!n%%p20){message(paste((n/p20)*5, "% done"))} + sel <- selectlist[[n]] lapply(specs[sel[-1]],network1, spec2 = specs[[sel[1]]], method = method, diff --git a/tests/testthat/_snaps/plotting/no-modifications.svg b/tests/testthat/_snaps/plotting/no-modifications.svg new file mode 100644 index 0000000..84054bd --- /dev/null +++ b/tests/testthat/_snaps/plotting/no-modifications.svg @@ -0,0 +1,275 @@ + + + + + + + + + + + + +A +S +D +F +G +H +K +L +I +P +Y +T +R +E +W +Q +C +N +M + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +b +18 +b +17 +b +16 +b +15 +b +14 +b +13 +b +12 +b +11 +b +10 +b +9 +b +8 +b +7 +b +6 +b +5 +b +4 +b +3 +b +2 +b +1 +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +2204.034 ++ +2089.991 ++ +1929.961 ++ +1801.902 ++ +1615.823 ++ +1486.78 ++ +1330.679 ++ +1229.631 ++ +1066.568 ++ +969.5152 ++ +856.4312 ++ +743.3471 ++ +615.2521 ++ +478.1932 ++ +421.1718 ++ +274.1034 ++ +159.0764 ++ +72.04439 ++ +y +18 +y +17 +y +16 +y +15 +y +14 +y +13 +y +12 +y +11 +y +10 +y +9 +y +8 +y +7 +y +6 +y +5 +y +4 +y +3 +y +2 +y +1 +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +2282.048 ++ +2195.016 ++ +2079.989 ++ +1932.921 ++ +1875.899 ++ +1738.84 ++ +1610.745 ++ +1497.661 ++ +1384.577 ++ +1287.525 ++ +1124.461 ++ +1023.413 ++ +867.3124 ++ +738.2698 ++ +552.1905 ++ +424.1319 ++ +264.1013 ++ +150.0583 ++ + + diff --git a/tests/testthat/_snaps/plotting/with-modifications.svg b/tests/testthat/_snaps/plotting/with-modifications.svg new file mode 100644 index 0000000..3c6c932 --- /dev/null +++ b/tests/testthat/_snaps/plotting/with-modifications.svg @@ -0,0 +1,455 @@ + + + + + + + + + + + + +A +S +D +F +G +H +K +L +I +P +Y +T +R +E +W +Q +C +N +M + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +b +18 +b +17 +b +16 +b +15 +b +14 +b +13 +b +12 +b +11 +b +10 +b +9 +b +8 +b +7 +b +6 +b +5 +b +4 +b +3 +b +2 +b +1 +[-2DH|2C] +[-2DH|2C] +[-2DH|2C] +[-2DH|2C] +[-2DH|2C] +[-2DH|2C] +[-2DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[2C] +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +2192.014 ++ +2077.971 ++ +1917.941 ++ +1789.882 ++ +1603.803 ++ +1474.76 ++ +1318.659 ++ +1235.621 ++ +1072.558 ++ +975.5052 ++ +862.4212 ++ +749.3371 ++ +621.2421 ++ +484.1832 ++ +427.1618 ++ +280.0934 ++ +165.0664 ++ +96.04439 ++ +[-2DH|1C] +[-2DH|1C] +[-2DH|1C] +[-2DH|1C] +[-2DH|1C] +[-2DH|1C] +[-2DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[1C] +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +2180.014 ++ +2065.971 ++ +1905.941 ++ +1777.882 ++ +1591.803 ++ +1462.76 ++ +1306.659 ++ +1223.621 ++ +1060.558 ++ +963.5052 ++ +850.4212 ++ +737.3371 ++ +609.2421 ++ +472.1832 ++ +415.1618 ++ +268.0934 ++ +153.0664 ++ +84.04439 ++ +y +18 +y +17 +y +16 +y +15 +y +14 +y +13 +y +12 +y +11 +y +10 +y +9 +y +8 +y +7 +y +6 +y +5 +y +4 +y +3 +y +2 +y +1 +[-2DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[-1DH|2C] +[2C] +[2C] +[2C] +[2C] +[2C] +[2C] +[2C] +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +2270.028 ++ +2201.006 ++ +2085.979 ++ +1938.911 ++ +1881.889 ++ +1744.83 ++ +1616.735 ++ +1503.651 ++ +1390.567 ++ +1293.515 ++ +1130.451 ++ +1047.414 ++ +891.3124 ++ +762.2698 ++ +576.1905 ++ +448.1319 ++ +288.1013 ++ +174.0583 ++ +[-2DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[-1DH|1C] +[1C] +[1C] +[1C] +[1C] +[1C] +[1C] +[1C] +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +(0.0) +2258.028 ++ +2189.006 ++ +2073.979 ++ +1926.911 ++ +1869.889 ++ +1732.83 ++ +1604.735 ++ +1491.651 ++ +1378.567 ++ +1281.515 ++ +1118.451 ++ +1035.414 ++ +879.3124 ++ +750.2698 ++ +564.1905 ++ +436.1319 ++ +276.1013 ++ +162.0583 ++ + + diff --git a/tests/testthat/test_calcMF.R b/tests/testthat/test_calcMF.R index ed1b250..e71727e 100644 --- a/tests/testthat/test_calcMF.R +++ b/tests/testthat/test_calcMF.R @@ -16,7 +16,7 @@ test_that("calcMF correctly passes through Rdisop::decomposeMass results",{ summarize = F, BPPARAM = NULL) - rdires <- Rdisop::decomposeMass(200.000659, + rdires <- Rdisop::decomposeMass(200.000659+ 1*5.48579909070e-4, z = 1, ppm = 5, mzabs = 0,