diff --git a/.github/workflows/check-bioc.yml b/.github/workflows/check-bioc.yml index 6372778e..09338ee6 100644 --- a/.github/workflows/check-bioc.yml +++ b/.github/workflows/check-bioc.yml @@ -54,8 +54,8 @@ jobs: matrix: config: - { os: ubuntu-latest, r: 'devel', bioc: 'devel', cont: "bioconductor/bioconductor_docker:devel", rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest" } - - { os: macOS-latest, r: 'next', bioc: '3.19'} - - { os: windows-latest, r: 'next', bioc: '3.19'} + - { os: macOS-latest, r: '4.4', bioc: 'devel'} + - { os: windows-latest, r: '4.4', bioc: 'devel'} env: R_REMOTES_NO_ERRORS_FROM_WARNINGS: true RSPM: ${{ matrix.config.rspm }} @@ -141,15 +141,15 @@ jobs: ## required for ncdf4 ## brew install netcdf ## Does not work as it is compiled with gcc ## Use pre-compiled libraries from https://mac.r-project.org/libs-4/ - curl -O https://mac.r-project.org/libs-4/netcdf-4.7.4-darwin.17-x86_64.tar.gz - tar fvxzm netcdf-4.7.4-darwin.17-x86_64.tar.gz -C / - rm netcdf-4.7.4-darwin.17-x86_64.tar.gz - curl -O https://mac.r-project.org/libs-4/hdf5-1.12.0-darwin.17-x86_64.tar.gz - tar fvxzm hdf5-1.12.0-darwin.17-x86_64.tar.gz -C / - rm hdf5-1.12.0-darwin.17-x86_64.tar.gz - curl -O https://mac.r-project.org/libs-4/szip-2.1.1-darwin.17-x86_64.tar.gz - tar fvxzm szip-2.1.1-darwin.17-x86_64.tar.gz -C / - rm szip-2.1.1-darwin.17-x86_64.tar.gz + # curl -O https://mac.r-project.org/libs-4/netcdf-4.7.4-darwin.17-x86_64.tar.gz + # tar fvxzm netcdf-4.7.4-darwin.17-x86_64.tar.gz -C / + # rm netcdf-4.7.4-darwin.17-x86_64.tar.gz + # curl -O https://mac.r-project.org/libs-4/hdf5-1.12.0-darwin.17-x86_64.tar.gz + # tar fvxzm hdf5-1.12.0-darwin.17-x86_64.tar.gz -C / + # rm hdf5-1.12.0-darwin.17-x86_64.tar.gz + # curl -O https://mac.r-project.org/libs-4/szip-2.1.1-darwin.17-x86_64.tar.gz + # tar fvxzm szip-2.1.1-darwin.17-x86_64.tar.gz -C / + # rm szip-2.1.1-darwin.17-x86_64.tar.gz - name: Install Windows system dependencies if: runner.os == 'Windows' diff --git a/DESCRIPTION b/DESCRIPTION index e700676d..e370ec7e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: xcms -Version: 4.3.0 +Version: 4.3.1 Title: LC-MS and GC-MS Data Analysis Description: Framework for processing and visualization of chromatographically separated and single-spectra mass spectral data. Imports from AIA/ANDI NetCDF, diff --git a/NAMESPACE b/NAMESPACE index 1592c843..3b122388 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -580,6 +580,7 @@ importFrom("MsExperiment", "sampleData<-") importFrom("MsExperiment", "sampleData") importFrom("MsExperiment", "readMsExperiment") importMethodsFrom("MsExperiment", "spectra<-") +export("plotPrecursorIons") importFrom("progress", "progress_bar") diff --git a/NEWS.md b/NEWS.md index 6d0da0e0..ecb3f7b3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,10 +1,20 @@ +# xcms 4.3 + +## Changes in version 4.3.1 + +- Support excluding samples or sample groups from defining features with + *PeakDensity* correspondence analysis (issue #742). +- Add `plotPrecursorIons()` function. +- Fix in `dropFeatureDefinitions()` that was not correctly removing additional + metadata from gap-filled chromatographic peaks. + + # xcms 4.1 ## Changes in version 4.1.14 - Fix for issue #734. XIC plot is is now working with MS2 Data. - ## Changes in version 4.1.13 - Add parameter `rtimeDifferenceThreshold` to `ObiwarpParam` allowing to diff --git a/R/AllGenerics.R b/R/AllGenerics.R index ec2cb71d..fbf47a96 100644 --- a/R/AllGenerics.R +++ b/R/AllGenerics.R @@ -1319,7 +1319,15 @@ setGeneric("group", function(object, ...) standardGeneric("group")) #' representing the m/z dependent measurement error of some MS instruments). #' All peaks (from the same or from different samples) with their apex #' position being close on the retention time axis are grouped into a LC-MS -#' feature. See in addition [do_groupChromPeaks_density()] for the core API +#' feature. Only samples with non-missing sample group assignment (i.e. for +#' which the value provided with parameter `sampleGroups` is different than +#' `NA`) are considered and counted for the feature definition. This allows +#' to exclude certain samples or groups (e.g. blanks) from the feature +#' definition avoiding thus features with only detected peaks in these. Note +#' that this affects only the **definition** of **new** features. +#' Chromatographic peaks in these samples will still be assigned to features +#' which were defined based on the other samples. +#' See in addition [do_groupChromPeaks_density()] for the core API #' function. #' #' - `NearestPeaksParam`: performs peak grouping based on the proximity of @@ -1399,11 +1407,13 @@ setGeneric("group", function(object, ...) standardGeneric("group")) #' #' @param sampleGroups For `PeakDensityParam`: A vector of the same length than #' samples defining the sample group assignments (i.e. which samples -#' belong to which sample -#' group). This parameter is mandatory for the `PeakDensityParam` -#' and has to be provided also if there is no sample grouping in the -#' experiment (in which case all samples should be assigned to the -#' same group). +#' belong to which sample group). This parameter is mandatory for +#' `PeakDensityParam` and has to be defined also if there is no sample +#' grouping in the experiment (in which case all samples should be +#' assigned to the same group). Samples for which a `NA` is provided will +#' not be considered in the feature definitions step. Providing `NA` for +#' all blanks in an experiment will for example avoid features to be +#' defined for signals (chrom peaks) present only in blank samples. #' #' @param value Replacement value for `<-` methods. #' diff --git a/R/XcmsExperiment-plotting.R b/R/XcmsExperiment-plotting.R index e657f751..ed16537b 100644 --- a/R/XcmsExperiment-plotting.R +++ b/R/XcmsExperiment-plotting.R @@ -406,3 +406,73 @@ setMethod( } } } + +#' @title General visualization of precursor ions of LC-MS/MS data +#' +#' @description +#' +#' Simple visualization of the position of fragment spectra's precursor ion +#' in the MS1 retention time by m/z area. +#' +#' @param x `MsExperiment` of LC-MS/MS data. +#' +#' @param pch `integer(1)` defining the symbol/point type to be used to draw +#' points. See [points()] for details. Defaults to `pch = 21` which allows +#' defining the background and border color for points. +#' +#' @param col the color to be used for all data points. Defines the border +#' color if `pch = 21`. +#' +#' @param bg the background color (if `pch = 21`). +#' +#' @param xlab `character(1)` defining the x-axis label. +#' +#' @param ylab `character(1)` defining the y-axis label. +#' +#' @param main Optional `character(1)` with the title for **every** plot. If +#' not provided (the default) the base file name will be used for each +#' sample. +#' +#' @param ... additional parameters to be passed to the `plot` calls. +#' +#' @importFrom grDevices n2mfrow +#' +#' @export +#' +#' @author Johannes Rainer +#' +#' @md +#' +#' @examples +#' +#' ## Load a test data file with DDA LC-MS/MS data +#' library(MsExperiment) +#' fl <- system.file("TripleTOF-SWATH", "PestMix1_DDA.mzML", package = "msdata") +#' pest_dda <- readMsExperiment(fl) +#' +#' plotPrecursorIons(pest_dda) +#' grid() +#' +#' ## Subset the data object to plot the data specifically for one or +#' ## selected file/sample: +#' plotPrecursorIons(pest_dda[1L]) +plotPrecursorIons <- function(x, pch = 21, col = "#00000080", + bg = "#00000020", xlab = "retention time", + ylab = "m/z", main = character(), ...) { + if (!inherits(x, "MsExperiment")) + stop("'x' should be a 'MsExperiment' object or an object of a ", + "class extending it.") + par(mfrow = n2mfrow(length(x))) + for (i in seq_along(x)) { + x_sub <- x[i] + rtr <- range(rtime(spectra(x_sub))) + mzr <- range(range(mz(filterEmptySpectra(spectra(x_sub))))) + pmz <- precursorMz(spectra(x_sub)) + prt <- rtime(spectra(x_sub)[!is.na(pmz)]) + pmz <- pmz[!is.na(pmz)] + if (!length(main)) + main <- basename(dataOrigin(spectra(x_sub)[1L])) + plot(prt, pmz, xlim = rtr, ylim = mzr, pch = pch, col = col, bg = bg, + xlab = xlab, ylab = ylab, main = main[1L], ...) + } +} diff --git a/R/XcmsExperiment.R b/R/XcmsExperiment.R index 1c86f049..356edbce 100644 --- a/R/XcmsExperiment.R +++ b/R/XcmsExperiment.R @@ -206,6 +206,9 @@ #' - `plotChromPeaks`: indicate identified chromatographic peaks from one #' sample in the RT-m/z space. See [plotChromPeaks()] for details. #' +#' - `plotPrecursorIons`: general visualization of precursor ions of +#' LC-MS/MS data. See [plotPrecursorIons()] for details. +#' #' - `refineChromPeaks`: *refines* identified chromatographic peaks in `object`. #' See [refineChromPeaks()] for details. #' @@ -1553,9 +1556,8 @@ setMethod( object@processHistory, type = .PROCSTEP.PEAK.GROUPING, num = 1L) object@featureDefinitions <- .empty_feature_definitions() if (.hasFilledPeaks(object)) { - object@chromPeaks <- object@chromPeaks[ - !object@chromPeakData$is_filled, , - drop = FALSE] + object <- .filter_chrom_peaks( + object, which(!.chromPeakData(object)$is_filled)) object@processHistory <- dropProcessHistoriesList( object@processHistory, type = .PROCSTEP.PEAK.FILLING) } diff --git a/R/do_groupChromPeaks-functions.R b/R/do_groupChromPeaks-functions.R index 1170ef44..85087eab 100644 --- a/R/do_groupChromPeaks-functions.R +++ b/R/do_groupChromPeaks-functions.R @@ -113,8 +113,11 @@ do_groupChromPeaks_density <- function(peaks, sampleGroups, paste0("'", .reqCols[!.reqCols %in% colnames(peaks)],"'", collapse = ", "), " not found in 'peaks' parameter") - sampleGroups <- as.character(sampleGroups) - sampleGroupNames <- unique(sampleGroups) + ## With a `factor` we also support excluding samples/groups, i.e. samples + ## with an NA are not considered in the feature definition. + if (!is.factor(sampleGroups)) + sampleGroups <- factor(sampleGroups) + sampleGroupNames <- levels(sampleGroups) sampleGroupTable <- table(sampleGroups) nSampleGroups <- length(sampleGroupTable) @@ -160,15 +163,12 @@ do_groupChromPeaks_density <- function(peaks, sampleGroups, pb$tick() if (endIdx - startIdx < 0) next - resL[[i]] <- .group_peaks_density(peaks[startIdx:endIdx, , drop = FALSE], - bw = bw, densFrom = densFrom, - densTo = densTo, densN = densN, - sampleGroups = sampleGroups, - sampleGroupTable = sampleGroupTable, - minFraction = minFraction, - minSamples = minSamples, - maxFeatures = maxFeatures, - sleep = sleep) + resL[[i]] <- .group_peaks_density( + peaks[startIdx:endIdx, , drop = FALSE], bw = bw, + densFrom = densFrom, densTo = densTo, densN = densN, + sampleGroups = sampleGroups, sampleGroupTable = sampleGroupTable, + minFraction = minFraction, minSamples = minSamples, + maxFeatures = maxFeatures, sleep = sleep) } res <- do.call(rbind, resL) if (nrow(res)) { diff --git a/R/functions-Params.R b/R/functions-Params.R index cbf00d36..d790162c 100644 --- a/R/functions-Params.R +++ b/R/functions-Params.R @@ -236,9 +236,8 @@ CentWavePredIsoParam <- function(ppm = 25, peakwidth = c(20, 50), snthresh = 10, PeakDensityParam <- function(sampleGroups = numeric(), bw = 30, minFraction = 0.5, minSamples = 1, binSize = 0.25, ppm = 0, maxFeatures = 50) { - if (length(sampleGroups) == 0 | any(is.na(sampleGroups))) - stop("Argument 'sampleGroups' has to be defined. It should not ", - "contain 'NA's") + if (length(sampleGroups) == 0) + stop("Argument 'sampleGroups' has to be defined.") new("PeakDensityParam", sampleGroups = sampleGroups, bw = bw, minFraction = minFraction, minSamples = minSamples, binSize = binSize, ppm = ppm, maxFeatures = maxFeatures) diff --git a/man/XcmsExperiment.Rd b/man/XcmsExperiment.Rd index de7e1c35..f7676365 100644 --- a/man/XcmsExperiment.Rd +++ b/man/XcmsExperiment.Rd @@ -580,6 +580,8 @@ peaks per file along the retention time. See \code{\link[=plotChromPeakImage]{pl details. \item \code{plotChromPeaks}: indicate identified chromatographic peaks from one sample in the RT-m/z space. See \code{\link[=plotChromPeaks]{plotChromPeaks()}} for details. +\item \code{plotPrecursorIons}: general visualization of precursor ions of +LC-MS/MS data. See \code{\link[=plotPrecursorIons]{plotPrecursorIons()}} for details. \item \code{refineChromPeaks}: \emph{refines} identified chromatographic peaks in \code{object}. See \code{\link[=refineChromPeaks]{refineChromPeaks()}} for details. } diff --git a/man/do_groupChromPeaks_density.Rd b/man/do_groupChromPeaks_density.Rd index 739e915c..6befbddd 100644 --- a/man/do_groupChromPeaks_density.Rd +++ b/man/do_groupChromPeaks_density.Rd @@ -27,11 +27,13 @@ the index of the sample in which the peak was found.} \item{sampleGroups}{For \code{PeakDensityParam}: A vector of the same length than samples defining the sample group assignments (i.e. which samples -belong to which sample -group). This parameter is mandatory for the \code{PeakDensityParam} -and has to be provided also if there is no sample grouping in the -experiment (in which case all samples should be assigned to the -same group).} +belong to which sample group). This parameter is mandatory for +\code{PeakDensityParam} and has to be defined also if there is no sample +grouping in the experiment (in which case all samples should be +assigned to the same group). Samples for which a \code{NA} is provided will +not be considered in the feature definitions step. Providing \code{NA} for +all blanks in an experiment will for example avoid features to be +defined for signals (chrom peaks) present only in blank samples.} \item{bw}{For \code{PeakDensityParam}: \code{numeric(1)} defining the bandwidth (standard deviation ot the smoothing kernel) to be used. This argument diff --git a/man/do_groupChromPeaks_nearest.Rd b/man/do_groupChromPeaks_nearest.Rd index 085f1bc1..92c29185 100644 --- a/man/do_groupChromPeaks_nearest.Rd +++ b/man/do_groupChromPeaks_nearest.Rd @@ -23,11 +23,13 @@ the index of the sample in which the peak was found.} \item{sampleGroups}{For \code{PeakDensityParam}: A vector of the same length than samples defining the sample group assignments (i.e. which samples -belong to which sample -group). This parameter is mandatory for the \code{PeakDensityParam} -and has to be provided also if there is no sample grouping in the -experiment (in which case all samples should be assigned to the -same group).} +belong to which sample group). This parameter is mandatory for +\code{PeakDensityParam} and has to be defined also if there is no sample +grouping in the experiment (in which case all samples should be +assigned to the same group). Samples for which a \code{NA} is provided will +not be considered in the feature definitions step. Providing \code{NA} for +all blanks in an experiment will for example avoid features to be +defined for signals (chrom peaks) present only in blank samples.} \item{mzVsRtBalance}{For \code{NearestPeaksParam}: \code{numeric(1)} representing the factor by which m/z values are multiplied before calculating the diff --git a/man/do_groupPeaks_mzClust.Rd b/man/do_groupPeaks_mzClust.Rd index dba42f79..48eb6d9c 100644 --- a/man/do_groupPeaks_mzClust.Rd +++ b/man/do_groupPeaks_mzClust.Rd @@ -22,11 +22,13 @@ the index of the sample in which the peak was found.} \item{sampleGroups}{For \code{PeakDensityParam}: A vector of the same length than samples defining the sample group assignments (i.e. which samples -belong to which sample -group). This parameter is mandatory for the \code{PeakDensityParam} -and has to be provided also if there is no sample grouping in the -experiment (in which case all samples should be assigned to the -same group).} +belong to which sample group). This parameter is mandatory for +\code{PeakDensityParam} and has to be defined also if there is no sample +grouping in the experiment (in which case all samples should be +assigned to the same group). Samples for which a \code{NA} is provided will +not be considered in the feature definitions step. Providing \code{NA} for +all blanks in an experiment will for example avoid features to be +defined for signals (chrom peaks) present only in blank samples.} \item{ppm}{For \code{MzClustParam}: \code{numeric(1)} representing the relative m/z error for the clustering/grouping (in parts per million). diff --git a/man/groupChromPeaks.Rd b/man/groupChromPeaks.Rd index 5a404952..7be3bf18 100644 --- a/man/groupChromPeaks.Rd +++ b/man/groupChromPeaks.Rd @@ -190,11 +190,13 @@ object will remove previous results.} \item{sampleGroups}{For \code{PeakDensityParam}: A vector of the same length than samples defining the sample group assignments (i.e. which samples -belong to which sample -group). This parameter is mandatory for the \code{PeakDensityParam} -and has to be provided also if there is no sample grouping in the -experiment (in which case all samples should be assigned to the -same group).} +belong to which sample group). This parameter is mandatory for +\code{PeakDensityParam} and has to be defined also if there is no sample +grouping in the experiment (in which case all samples should be +assigned to the same group). Samples for which a \code{NA} is provided will +not be considered in the feature definitions step. Providing \code{NA} for +all blanks in an experiment will for example avoid features to be +defined for signals (chrom peaks) present only in blank samples.} \item{bw}{For \code{PeakDensityParam}: \code{numeric(1)} defining the bandwidth (standard deviation ot the smoothing kernel) to be used. This argument @@ -271,7 +273,15 @@ larger than 0, m/z dependent bin sizes can be used instead (better representing the m/z dependent measurement error of some MS instruments). All peaks (from the same or from different samples) with their apex position being close on the retention time axis are grouped into a LC-MS -feature. See in addition \code{\link[=do_groupChromPeaks_density]{do_groupChromPeaks_density()}} for the core API +feature. Only samples with non-missing sample group assignment (i.e. for +which the value provided with parameter \code{sampleGroups} is different than +\code{NA}) are considered and counted for the feature definition. This allows +to exclude certain samples or groups (e.g. blanks) from the feature +definition avoiding thus features with only detected peaks in these. Note +that this affects only the \strong{definition} of \strong{new} features. +Chromatographic peaks in these samples will still be assigned to features +which were defined based on the other samples. +See in addition \code{\link[=do_groupChromPeaks_density]{do_groupChromPeaks_density()}} for the core API function. \item \code{NearestPeaksParam}: performs peak grouping based on the proximity of chromatographic peaks from different samples in the m/z - rt space similar diff --git a/man/plotPrecursorIons.Rd b/man/plotPrecursorIons.Rd new file mode 100644 index 00000000..aaf7f7fe --- /dev/null +++ b/man/plotPrecursorIons.Rd @@ -0,0 +1,60 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/XcmsExperiment-plotting.R +\name{plotPrecursorIons} +\alias{plotPrecursorIons} +\title{General visualization of precursor ions of LC-MS/MS data} +\usage{ +plotPrecursorIons( + x, + pch = 21, + col = "#00000080", + bg = "#00000020", + xlab = "retention time", + ylab = "m/z", + main = character(), + ... +) +} +\arguments{ +\item{x}{\code{MsExperiment} of LC-MS/MS data.} + +\item{pch}{\code{integer(1)} defining the symbol/point type to be used to draw +points. See \code{\link[=points]{points()}} for details. Defaults to \code{pch = 21} which allows +defining the background and border color for points.} + +\item{col}{the color to be used for all data points. Defines the border +color if \code{pch = 21}.} + +\item{bg}{the background color (if \code{pch = 21}).} + +\item{xlab}{\code{character(1)} defining the x-axis label.} + +\item{ylab}{\code{character(1)} defining the y-axis label.} + +\item{main}{Optional \code{character(1)} with the title for \strong{every} plot. If +not provided (the default) the base file name will be used for each +sample.} + +\item{...}{additional parameters to be passed to the \code{plot} calls.} +} +\description{ +Simple visualization of the position of fragment spectra's precursor ion +in the MS1 retention time by m/z area. +} +\examples{ + +## Load a test data file with DDA LC-MS/MS data +library(MsExperiment) +fl <- system.file("TripleTOF-SWATH", "PestMix1_DDA.mzML", package = "msdata") +pest_dda <- readMsExperiment(fl) + +plotPrecursorIons(pest_dda) +grid() + +## Subset the data object to plot the data specifically for one or +## selected file/sample: +plotPrecursorIons(pest_dda[1L]) +} +\author{ +Johannes Rainer +} diff --git a/tests/testthat/test_Param_classes.R b/tests/testthat/test_Param_classes.R index 5a3eb6f8..4281d56f 100644 --- a/tests/testthat/test_Param_classes.R +++ b/tests/testthat/test_Param_classes.R @@ -500,7 +500,6 @@ test_that("PeakDensityParam works", { expect_error(sampleGroups(p) <- NULL) expect_error(sampleGroups(p) <- c(2, 2, NA)) expect_error(PeakDensityParam()) - expect_error(PeakDensityParam(sampleGroups = c(1, 1, NA))) p <- new("PeakDensityParam", bw = 3) expect_equal(bw(p), 3) diff --git a/tests/testthat/test_XcmsExperiment-plotting.R b/tests/testthat/test_XcmsExperiment-plotting.R index 312d0a87..a4ab590a 100644 --- a/tests/testthat/test_XcmsExperiment-plotting.R +++ b/tests/testthat/test_XcmsExperiment-plotting.R @@ -53,6 +53,19 @@ test_that("plot,XcmsExperiment and .xmse_plot_xic works", { plot(tmp) }) +test_that("plotPrecursorIons works", { + expect_error(plotPrecursorIons(3), "MsExperiment") + fl <- system.file("TripleTOF-SWATH", "PestMix1_SWATH.mzML", + package = "msdata") + a <- readMsExperiment(fl) + plotPrecursorIons(a, main = "SWATH") + + fl <- system.file("TripleTOF-SWATH", "PestMix1_DDA.mzML", + package = "msdata") + a <- readMsExperiment(fl) + plotPrecursorIons(a) +}) + test_that(".xmse_plot_xic works with ms2 data", { tmp <- filterMz(filterRt(mse_ms2, rt= c(2160, 2190)), mz = c(990,1000)) plot(tmp) diff --git a/tests/testthat/test_do_groupChromPeaks-functions.R b/tests/testthat/test_do_groupChromPeaks-functions.R index f01f3617..56e49e96 100644 --- a/tests/testthat/test_do_groupChromPeaks-functions.R +++ b/tests/testthat/test_do_groupChromPeaks-functions.R @@ -85,3 +85,37 @@ test_that(".group_peaks_density works", { expect_true(nrow(res) == 0) expect_true(is(res, "data.frame")) }) + +test_that("do_groupChromPeaks_density works with skipping samples", { + x <- loadXcmsData("xmse") + pks <- chromPeaks(x) + ## Errors + expect_error(do_groupChromPeaks_density(pks), "sampleGroups") + expect_error(do_groupChromPeaks_density(3, sampleGroups = 3), "matrix") + expect_error(do_groupChromPeaks_density(pks[, 1:3], sampleGroups = 1), + "not found") + expect_error(do_groupChromPeaks_density(pks, sampleGroups = 1:3), + "Sample indices") + + ## groups for all samples. + grps <- sampleData(x)$sample_group + res <- do_groupChromPeaks_density(pks, sampleGroups = grps, + minFraction = 1, bw = 30) + expect_true(all(res$WT == 4 | res$KO == 4)) + expect_true(all(res$WT <= 4)) + expect_true(all(res$KO <= 4)) + + res_2 <- do_groupChromPeaks_density( + pks, sampleGroups = rep(1, length(grps)), minFraction = 1) + expect_true(nrow(res_2) < nrow(res)) + expect_true(all(res_2$`1` == 8)) + + ## using only one sample group + grps[grps == "KO"] <- NA + res_3 <- do_groupChromPeaks_density(pks, sampleGroups = grps, + minFraction = 1) + expect_true(nrow(res_3) < nrow(res)) + expect_true(all(res_3$WT == 4)) + expect_equal(nrow(res_3), sum(res$WT == 4)) + tmp <- res[res$WT == 4, ] +})